├── ch20 ├── alt │ ├── cgihttpd2.py │ ├── cgihttpd.py │ ├── friends1.py │ ├── myhttpd.py │ ├── friends2.py │ ├── friends3.py │ ├── advcgi.py │ └── advcgi2.py ├── uniCGI.py ├── friends1.py ├── friends.htm ├── urlopenAuth.py ├── myhttpd.py ├── friends2.py ├── friends3.py ├── crawl.py └── advcgi.py ├── ch16 ├── alt │ ├── ts.zip │ ├── tsTclntSSBRH.py │ ├── tsTclntNew.py │ ├── tsTservSS.py │ ├── tsTservSSBRH.py │ ├── tsUserv.py │ ├── tsTserv.py │ └── tsTservNew.py ├── tsUclnt.py ├── tsTclnt.py ├── tsTclntSS.py ├── tsUserv.py ├── tsTservSS.py ├── tsTservTW.py ├── tsTserv.py └── tsTclntTW.py ├── ch14 ├── alt │ ├── xcount.py │ └── loopmake.py ├── args.py ├── funcAttrs.py └── loopmake.py ├── ch19 ├── tkhello1.py ├── tkhello2.py ├── tkhello3.py ├── alt │ ├── tkhello0.py │ ├── tkhello2.py │ ├── tkhello1.py │ ├── tkhello4.py │ └── listdir.py ├── tkhello4.py ├── animalTix.pyw ├── animalPmw.pyw ├── pfaGUI2.py ├── animalWx.pyw ├── animalGtk.pyw └── listdir.py ├── ch10 ├── carddata.txt ├── cardlog.txt ├── cardrun.py ├── alt │ ├── cardrun.py │ └── myexc.py └── myexc.py ├── ch22 ├── setup.py ├── Extest1.c └── Extest2.c ├── ch11 ├── alt │ ├── simpleGen.py │ ├── randGen.py │ ├── counter.py │ ├── scope.py │ └── deco.py ├── numConv.py ├── deco.py ├── scope.py ├── pfaGUI.py ├── grabWeb.py ├── testit.py ├── closureVars.py ├── funcLog.py └── easyMath.py ├── ch15 ├── rewho.py ├── alt │ ├── rewho.py │ └── gendata.py └── gendata.py ├── ch06 ├── alt │ ├── stringTemplates.py │ ├── NoneIndex.py │ ├── insertVsColonZero.py │ ├── idcheck2.py │ ├── reversedSorted.py │ ├── idcheck.py │ ├── stack.py │ └── queue.py ├── uniFile.py ├── buggy.py ├── idcheck.py ├── queue.py └── stack.py ├── ch13 ├── randSeq.py ├── roundFloat2.py ├── capOpen.py ├── hotel.py ├── anyIter.py ├── alt │ ├── metaIntro.py │ ├── anyIter.py │ ├── hotel.py │ ├── capOpen.py │ ├── descr-tef.py │ ├── descr-with.py │ ├── twrapme.py │ ├── descr.py │ └── moneyfmt.py ├── time60.py ├── moneyfmt.py ├── ProtectAndHideX.py ├── descrPRE25.diff ├── descr.diff ├── twrapme.py ├── meta.py ├── descr.py ├── descr0.py ├── descrPRE25.py └── numstr.py ├── ch08 ├── maxFact.py └── alt │ └── maxFact.py ├── ch04 └── typechk.py ├── ch03 ├── readTextFile.py ├── makeTextFile0.py ├── makeTextFile.py ├── makeTextFile.diff └── makeTextFile1.py ├── ch18 ├── onethr.py ├── myThread.py ├── mtsleep1.py ├── mtsleep3.py ├── mtsleep2.py ├── mtsleep5.py ├── mtsleep4.py ├── mtfacfib.py ├── prodcons.py └── alt │ └── mtfacfib.py ├── ch23 ├── swhello.py ├── stock.py ├── excel.pyw ├── word.pyw ├── ppoint.pyw ├── olook.pyw ├── swhello.java ├── alt │ └── win32demo.pyw └── estock.pyw ├── .gitignore ├── ch17 ├── myMail.py ├── getLatestFTP.py └── getLatestNNTP.py ├── ch07 ├── userpw.py └── alt │ └── userpw.py ├── README.md ├── ch09 ├── ospathex.py └── alt │ └── ospathex.py └── ch21 ├── ushuffle_so.py ├── ushuffle_sa.py ├── ushuffle_db.py └── alt └── ushuffle_dbPRE25.py /ch20/alt/cgihttpd2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from CGIHTTPServer import test;test() 4 | -------------------------------------------------------------------------------- /ch16/alt/ts.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gexos/Core-Python-Programming-2nd-Edition-Examples-and-Source-Code/HEAD/ch16/alt/ts.zip -------------------------------------------------------------------------------- /ch14/alt/xcount.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | x = 0 4 | print 'x is currently:', x 5 | while x < 5: 6 | x += 1 7 | print 'incrementing x to:', x 8 | -------------------------------------------------------------------------------- /ch19/tkhello1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import Tkinter 4 | 5 | top = Tkinter.Tk() 6 | label = Tkinter.Label(top, text='Hello World!') 7 | label.pack() 8 | Tkinter.mainloop() 9 | -------------------------------------------------------------------------------- /ch10/carddata.txt: -------------------------------------------------------------------------------- 1 | # carddata.txt 2 | previous balance 3 | 25 4 | debits 5 | 21.64 6 | 541.24 7 | 25 8 | credits 9 | -25 10 | -541.24 11 | finance charge/late fees 12 | 7.30 13 | 5 14 | -------------------------------------------------------------------------------- /ch22/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from distutils.core import setup, Extension 4 | 5 | MOD = 'Extest' 6 | setup(name=MOD, ext_modules=[ 7 | Extension(MOD, sources=['Extest2.c'])]) 8 | -------------------------------------------------------------------------------- /ch11/alt/simpleGen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def simpleGen(): 4 | yield 1 5 | yield '2 --> punch!' 6 | 7 | if __name__ == '__main__': 8 | for item in simpleGen(): 9 | print item 10 | -------------------------------------------------------------------------------- /ch15/rewho.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from os import popen 4 | from re import split 5 | 6 | f = popen('who', 'r') 7 | for eachLine in f: 8 | print split('\s\s+|\t', eachLine.strip()) 9 | f.close() 10 | -------------------------------------------------------------------------------- /ch19/tkhello2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import Tkinter 4 | 5 | top = Tkinter.Tk() 6 | quit = Tkinter.Button(top, text='Hello World!', 7 | command=top.quit) 8 | quit.pack() 9 | Tkinter.mainloop() 10 | -------------------------------------------------------------------------------- /ch06/alt/stringTemplates.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from string import Template 4 | s = Template('There are ${howmany} ${lang} Quotation Symbols') 5 | print s.substitute(lang='Python', howmany=3) 6 | print s.substitute(lang='Python') 7 | print s.safe_substitute(lang='Python') 8 | raw_input() 9 | -------------------------------------------------------------------------------- /ch11/alt/randGen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from random import randrange as rr 4 | 5 | def randGen(aList): 6 | while aList: 7 | yield aList.pop(rr(len(aList))) 8 | 9 | if __name__ == '__main__': 10 | for item in randGen(['rock', 'paper', 'scissors']): 11 | print item 12 | -------------------------------------------------------------------------------- /ch13/randSeq.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from random import choice 4 | 5 | class RandSeq(object): 6 | def __init__(self, seq): 7 | self.data = seq 8 | 9 | def __iter__(self): 10 | return self 11 | 12 | def next(self): 13 | return choice(self.data) 14 | -------------------------------------------------------------------------------- /ch20/alt/cgihttpd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from CGIHTTPServer import test 4 | 5 | if __name__ == '__main__': 6 | try: 7 | print 'Welcome to the machine...\nPress ^C once or twice to quit' 8 | test() 9 | except KeyboardInterrupt: 10 | print 'exiting server...' 11 | -------------------------------------------------------------------------------- /ch11/numConv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def convert(func, seq): 4 | 'conv. sequence of numbers to same type' 5 | return [func(eachNum) for eachNum in seq] 6 | 7 | myseq = (123, 45.67, -6.2e8, 999999999L) 8 | print convert(int, myseq) 9 | print convert(long, myseq) 10 | print convert(float, myseq) 11 | -------------------------------------------------------------------------------- /ch06/alt/NoneIndex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | s = 'abcde' 4 | 5 | #for x,y in enumerate(s): 6 | # print s[x:], s[:x] 7 | #for i in range(len(s), -1, -1): 8 | #print s[i:], s[:i], s[i::-1], s[:i:-1] 9 | 10 | s = 'abcde' 11 | for i in [None] + range(-1, -len(s), -1): 12 | print s[:i] 13 | 14 | raw_input() 15 | -------------------------------------------------------------------------------- /ch19/tkhello3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import Tkinter 4 | top = Tkinter.Tk() 5 | 6 | hello = Tkinter.Label(top, text='Hello World!') 7 | hello.pack() 8 | 9 | quit = Tkinter.Button(top, text='QUIT', 10 | command=top.quit, bg='red', fg='white') 11 | quit.pack(fill=Tkinter.X, expand=1) 12 | 13 | Tkinter.mainloop() 14 | -------------------------------------------------------------------------------- /ch13/roundFloat2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | class RoundFloatManual(object): 4 | def __init__(self, val): 5 | assert isinstance(val, float), \ 6 | "Value must be a float!" 7 | self.value = round(val, 2) 8 | 9 | def __str__(self): 10 | return '%.2f' % self.value 11 | 12 | __repr__ = __str__ 13 | -------------------------------------------------------------------------------- /ch14/args.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | def usage(): 6 | print 'At least 2 arguments (incl. cmd name).' 7 | print 'usage: args.py arg1 arg2 [arg3... ]' 8 | sys.exit(1) 9 | 10 | argc = len(sys.argv) 11 | if argc < 3: 12 | usage() 13 | print "number of args entered:", argc 14 | print "args (incl. cmd name) were:", sys.argv 15 | -------------------------------------------------------------------------------- /ch11/deco.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from time import ctime, sleep 4 | 5 | def tsfunc(func): 6 | def wrappedFunc(): 7 | print '[%s] %s() called' % ( 8 | ctime(), func.__name__) 9 | return func() 10 | return wrappedFunc 11 | 12 | @tsfunc 13 | def foo(): 14 | pass 15 | 16 | foo() 17 | sleep(4) 18 | 19 | for i in range(2): 20 | sleep(1) 21 | foo() 22 | -------------------------------------------------------------------------------- /ch20/uniCGI.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | CODEC = 'UTF-8' 4 | UNICODE_HELLO = u''' 5 | Hello! 6 | \u00A1Hola! 7 | \u4F60\u597D! 8 | \u3053\u3093\u306B\u3061\u306F! 9 | ''' 10 | 11 | print 'Content-Type: text/html; charset=%s\r' % CODEC 12 | print '\r' 13 | print 'Unicode CGI Demo' 14 | print '' 15 | print UNICODE_HELLO.encode(CODEC) 16 | print '' 17 | -------------------------------------------------------------------------------- /ch08/maxFact.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def showMaxFactor(num): 4 | count = num // 2 5 | while count > 1: 6 | if num % count == 0: 7 | print 'largest factor of %d is %d' % \ 8 | (num, count) 9 | break 10 | count -= 1 11 | else: 12 | print eachNum, 'is prime' 13 | 14 | for eachNum in range(10, 21): 15 | showMaxFactor(eachNum) 16 | -------------------------------------------------------------------------------- /ch04/typechk.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def displayNumType(num): 4 | print num, 'is', 5 | if isinstance(num, (int, long, float, complex)): 6 | print 'a number of type:', type(num).__name__ 7 | else: 8 | print 'not a number at all!!' 9 | 10 | displayNumType(-69) 11 | displayNumType(9999999999999999999999L) 12 | displayNumType(98.6) 13 | displayNumType(-5.2+1.9j) 14 | displayNumType('xxx') 15 | -------------------------------------------------------------------------------- /ch11/scope.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | j, k = 1, 2 3 | 4 | def proc1(): 5 | 6 | j, k = 3, 4 7 | print "j == %d and k == %d" % (j, k) 8 | k = 5 9 | 10 | def proc2(): 11 | 12 | #global j 13 | j = 6 14 | proc1() 15 | print "j == %d and k == %d" % (j, k) 16 | 17 | k = 7 18 | proc1() 19 | print "j == %d and k == %d" % (j, k) 20 | 21 | j = 8 22 | proc2() 23 | print "j == %d and k == %d" % (j, k) 24 | -------------------------------------------------------------------------------- /ch19/alt/tkhello0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id: tkhello0.py,v 1.1 2000/02/21 09:04:25 wesc Exp $ 3 | # 4 | # tkhello0.py -- "Hello World!" 0 in Tkinter: 5 | # - "Hello World!" label (need to close window to quit) 6 | # - just like tkhello1.py except for no toplevel 7 | # 8 | # created by wesc 00/02/20 9 | # 10 | 11 | import Tkinter 12 | label = Tkinter.Label(text='Hello World!') 13 | label.pack() 14 | label.mainloop() 15 | -------------------------------------------------------------------------------- /ch03/readTextFile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 'readTextFile.py -- read and display text file' 4 | 5 | # get filename 6 | fname = raw_input('Enter file name: ') 7 | print 8 | 9 | # attempt to open file for reading 10 | try: 11 | fobj = open(fname, 'r') 12 | except IOError, e: 13 | print"*** file open error:", e 14 | else: 15 | # display contents to the screen 16 | for eachLine in fobj: 17 | print eachLine, 18 | fobj.close() 19 | -------------------------------------------------------------------------------- /ch11/pfaGUI.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/python2.5 2 | 3 | from functools import partial 4 | import Tkinter 5 | 6 | root = Tkinter.Tk() 7 | MyButton = partial(Tkinter.Button, 8 | root, fg='white', bg='blue') 9 | b1 = MyButton(text='Button 1') 10 | b2 = MyButton(text='Button 2') 11 | qb = MyButton(text='QUIT', bg='red', 12 | command=root.quit) 13 | b1.pack() 14 | b2.pack() 15 | qb.pack(fill=Tkinter.X, expand=True) 16 | root.title('PFAs!') 17 | root.mainloop() 18 | -------------------------------------------------------------------------------- /ch16/alt/tsTclntSSBRH.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from socket import * 4 | 5 | HOST = 'localhost' 6 | PORT = 21567 7 | BUFSIZ = 1024 8 | ADDR = (HOST, PORT) 9 | 10 | while True: 11 | tcpCliSock = socket(AF_INET, SOCK_STREAM) 12 | tcpCliSock.connect(ADDR) 13 | data = raw_input('> ') 14 | if not data: 15 | break 16 | tcpCliSock.send(data) 17 | data = tcpCliSock.recv(BUFSIZ) 18 | if not data: 19 | break 20 | print data 21 | tcpCliSock.close() 22 | -------------------------------------------------------------------------------- /ch13/capOpen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | class CapOpen(object): 4 | def __init__(self, fn, mode='r', buf=-1): 5 | self.file = open(fn, mode, buf) 6 | 7 | def __str__(self): 8 | return str(self.file) 9 | 10 | def __repr__(self): 11 | return `self.file` 12 | 13 | def write(self, line): 14 | return self.file.write(line.upper()) 15 | 16 | def __getattr__(self, attr): 17 | return getattr(self.file, attr) 18 | -------------------------------------------------------------------------------- /ch20/friends1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import cgi 4 | 5 | reshtml = '''Content-Type: text/html\n 6 | 7 | Friends CGI Demo (dynamic screen) 8 | 9 |

Friends list for: %s

10 | Your name is: %s

11 | You have %s friends. 12 | ''' 13 | 14 | form = cgi.FieldStorage() 15 | who = form['person'].value 16 | howmany = form['howmany'].value 17 | print reshtml % (who, who, howmany) 18 | -------------------------------------------------------------------------------- /ch16/tsUclnt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from socket import * 4 | 5 | HOST = 'localhost' 6 | PORT = 21567 7 | BUFSIZ = 1024 8 | ADDR = (HOST, PORT) 9 | 10 | udpCliSock = socket(AF_INET, SOCK_DGRAM) 11 | 12 | while True: 13 | data = raw_input('> ') 14 | if not data: 15 | break 16 | udpCliSock.sendto(data, ADDR) 17 | data, ADDR = udpCliSock.recvfrom(BUFSIZ) 18 | if not data: 19 | break 20 | print data 21 | 22 | udpCliSock.close() 23 | -------------------------------------------------------------------------------- /ch10/cardlog.txt: -------------------------------------------------------------------------------- 1 | account log: 2 | ignored: invalid literal for float(): # carddata.txt 3 | ignored: invalid literal for float(): previous balance 4 | data... processed 5 | ignored: invalid literal for float(): debits 6 | data... processed 7 | data... processed 8 | data... processed 9 | ignored: invalid literal for float(): credits 10 | data... processed 11 | data... processed 12 | ignored: invalid literal for float(): finance charge/late fees 13 | data... processed 14 | data... processed 15 | -------------------------------------------------------------------------------- /ch16/tsTclnt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from socket import * 4 | 5 | HOST = 'localhost' 6 | PORT = 21567 7 | BUFSIZ = 1024 8 | ADDR = (HOST, PORT) 9 | 10 | tcpCliSock = socket(AF_INET, SOCK_STREAM) 11 | tcpCliSock.connect(ADDR) 12 | 13 | while True: 14 | data = raw_input('> ') 15 | if not data: 16 | break 17 | tcpCliSock.send(data) 18 | data = tcpCliSock.recv(BUFSIZ) 19 | if not data: 20 | break 21 | print data 22 | 23 | tcpCliSock.close() 24 | -------------------------------------------------------------------------------- /ch06/uniFile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | An example of reading and writing Unicode strings: Writes 4 | a Unicode string to a file in utf-8 and reads it back in. 5 | ''' 6 | CODEC = 'utf-8' 7 | FILE = 'unicode.txt' 8 | 9 | hello_out = u"Hello world\n" 10 | bytes_out = hello_out.encode(CODEC) 11 | f = open(FILE, "w") 12 | f.write(bytes_out) 13 | f.close() 14 | 15 | f = open(FILE, "r") 16 | bytes_in = f.read() 17 | f.close() 18 | hello_in = bytes_in.decode(CODEC) 19 | print hello_in, 20 | -------------------------------------------------------------------------------- /ch18/onethr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from time import sleep, ctime 4 | 5 | def loop0(): 6 | print 'start loop 0 at:', ctime() 7 | sleep(4) 8 | print 'loop 0 done at:', ctime() 9 | 10 | def loop1(): 11 | print 'start loop 1 at:', ctime() 12 | sleep(2) 13 | print 'loop 1 done at:', ctime() 14 | 15 | def main(): 16 | print 'starting at:', ctime() 17 | loop0() 18 | loop1() 19 | print 'all DONE at:', ctime() 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /ch16/alt/tsTclntNew.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from socket import * 4 | 5 | HOST = 'localhost' 6 | PORT = 21567 7 | BUFSIZ = 1024 8 | ADDR = (HOST, PORT) 9 | 10 | tcpCliSock = socket(AF_INET, SOCK_STREAM) 11 | tcpCliSock.connect(ADDR) 12 | 13 | while True: 14 | data = raw_input('> ') 15 | if not data: 16 | break 17 | tcpCliSock.send(data) 18 | print " ... waiting for reply ..." 19 | data = tcpCliSock.recv(BUFSIZ) 20 | if not data: 21 | break 22 | print data 23 | 24 | tcpCliSock.close() 25 | -------------------------------------------------------------------------------- /ch16/tsTclntSS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from socket import * 4 | 5 | HOST = 'localhost' 6 | PORT = 21567 7 | BUFSIZ = 1024 8 | ADDR = (HOST, PORT) 9 | 10 | while True: 11 | tcpCliSock = socket(AF_INET, SOCK_STREAM) 12 | tcpCliSock.connect(ADDR) 13 | data = raw_input('> ') 14 | if not data: 15 | break 16 | tcpCliSock.send('%s\r\n' % data) 17 | data = tcpCliSock.recv(BUFSIZ) 18 | if not data: 19 | break 20 | print data.strip() 21 | tcpCliSock.close() 22 | -------------------------------------------------------------------------------- /ch16/tsUserv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from socket import * 4 | from time import ctime 5 | 6 | HOST = '' 7 | PORT = 21567 8 | BUFSIZ = 1024 9 | ADDR = (HOST, PORT) 10 | 11 | udpSerSock = socket(AF_INET, SOCK_DGRAM) 12 | udpSerSock.bind(ADDR) 13 | 14 | while True: 15 | print 'waiting for message...' 16 | data, addr = udpSerSock.recvfrom(BUFSIZ) 17 | udpSerSock.sendto('[%s] %s' % ( 18 | ctime(), data), addr) 19 | print '...received from and returned to:', addr 20 | 21 | udpSerSock.close() 22 | -------------------------------------------------------------------------------- /ch16/tsTservSS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from SocketServer import (TCPServer as TCP, 4 | StreamRequestHandler as SRH) 5 | from time import ctime 6 | 7 | HOST = '' 8 | PORT = 21567 9 | ADDR = (HOST, PORT) 10 | 11 | class MyRequestHandler(SRH): 12 | def handle(self): 13 | print '...connected from:', self.client_address 14 | self.wfile.write('[%s] %s' % (ctime(), 15 | self.rfile.readline())) 16 | 17 | tcpServ = TCP(ADDR, MyRequestHandler) 18 | print 'waiting for connection...' 19 | tcpServ.serve_forever() 20 | -------------------------------------------------------------------------------- /ch23/swhello.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env jython 2 | 3 | from pawt import swing 4 | import sys 5 | from java.awt import Color, BorderLayout 6 | 7 | def quit(e): 8 | sys.exit() 9 | 10 | top = swing.JFrame("PySwing") 11 | box = swing.JPanel(BorderLayout()) 12 | hello = swing.JLabel("Hello World!") 13 | quit = swing.JButton("QUIT", actionPerformed=quit, 14 | background=Color.red, foreground=Color.white) 15 | 16 | box.add("North", hello) 17 | box.add("South", quit) 18 | top.contentPane.add(box) 19 | top.pack() 20 | top.visible = 1 # or True for Jython 2.2+ 21 | -------------------------------------------------------------------------------- /ch13/hotel.py: -------------------------------------------------------------------------------- 1 | class HotelRoomCalc: 2 | 'Hotel room rate calculator' 3 | 4 | def __init__(self, rt, sales=0.085, rm=0.1): 5 | '''HotelRoolCalc default arguments: 6 | sales tax == 8.5% and room tax == 10%''' 7 | self.salesTax = sales 8 | self.roomTax = rm 9 | self.roomRate = rt 10 | 11 | def calcTotal(self, days=1): 12 | 'Calculate total; default to daily rate' 13 | daily = round((self.roomRate * \ 14 | (1 + self.roomTax + self.salesTax)), 2) 15 | return float(days) * daily 16 | -------------------------------------------------------------------------------- /ch19/alt/tkhello2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id: tkhello2.py,v 1.1 2000/02/21 09:04:25 wesc Exp $ 3 | # 4 | # tkhello2.py -- "Hello World!" 2 in Tkinter: 5 | # - "Hello World!" with just a button (which quits the app) 6 | # 7 | # created by wesc 00/02/20 8 | # 9 | 10 | # import Tkinter module 11 | import Tkinter 12 | 13 | # create toplevel window 14 | top = Tkinter.Tk() 15 | 16 | # create button 17 | quit = Tkinter.Button(top, text='Hello World!', command=top.quit) 18 | 19 | # pack button 20 | quit.pack() 21 | 22 | # enter main loop 23 | Tkinter.mainloop() 24 | -------------------------------------------------------------------------------- /ch16/alt/tsTservSS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from SocketServer import (TCPServer as TCP, 4 | StreamRequestHandler as SRH) 5 | from time import ctime 6 | 7 | HOST = '' 8 | PORT = 21567 9 | ADDR = (HOST, PORT) 10 | 11 | class MyRequestHandler(SRH): 12 | def handle(self): 13 | print '...connected from:', self.client_address 14 | self.wfile.write('[%s] %s' % (ctime(), 15 | self.rfile.readline())) 16 | 17 | tcpServ = TCP(ADDR, MyRequestHandler) 18 | tcpServ.allow_reuse_address = True 19 | print 'waiting for connection...' 20 | tcpServ.serve_forever() 21 | -------------------------------------------------------------------------------- /ch16/alt/tsTservSSBRH.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from SocketServer import BaseRequestHandler as BRH, TCPServer as TCP 4 | from time import ctime 5 | 6 | HOST = '' 7 | PORT = 21567 8 | BUFSIZ = 1024 9 | ADDR = (HOST, PORT) 10 | 11 | class MyRequestHandler(BRH): 12 | def handle(self): 13 | print '...connected from:', self.client_address 14 | self.request.send('[%s] %s' % (ctime(), 15 | self.request.recv(BUFSIZ))) 16 | 17 | tcpServ = TCP(ADDR, MyRequestHandler) 18 | tcpServ.allow_reuse_address = True 19 | print 'waiting for connection...' 20 | tcpServ.serve_forever() 21 | -------------------------------------------------------------------------------- /ch15/alt/rewho.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from os import popen # import os.popen() 4 | from re import split # import re.split() [not string.split()] 5 | from string import strip # import string.strip() 6 | 7 | f = popen('who', 'r') # call the 'who' cmd and read from it 8 | 9 | # read all output from 'who' and strip the leading & trailing whitespaces 10 | for eachLine in map(strip, f.readlines()): 11 | print split('\s\s+|\t', eachLine) # split on TAB or multiple SPACEs 12 | f.close() # close input channel 13 | -------------------------------------------------------------------------------- /ch18/myThread.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import threading 4 | from time import time, ctime 5 | 6 | class MyThread(threading.Thread): 7 | def __init__(self, func, args, name=''): 8 | threading.Thread.__init__(self) 9 | self.name = name 10 | self.func = func 11 | self.args = args 12 | 13 | def getResult(self): 14 | return self.res 15 | 16 | def run(self): 17 | print 'starting', self.name, 'at:', \ 18 | ctime() 19 | self.res = apply(self.func, self.args) 20 | print self.name, 'finished at:', \ 21 | ctime() 22 | -------------------------------------------------------------------------------- /ch06/alt/insertVsColonZero.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from time import time 4 | REPS = 17500 5 | 6 | def insert(): 7 | m = [None] 8 | i = 0 9 | now = time() 10 | while i < REPS: 11 | m.insert(0, i) 12 | i += 1 13 | print 'Elapsed (insert):', time() - now 14 | 15 | def colonZero(): 16 | m = [None] 17 | i = 0 18 | now = time() 19 | while i < REPS: 20 | m[:0] = [i] 21 | i += 1 22 | print 'Elapsed (colon-0):', time() - now 23 | 24 | def main(): 25 | insert() 26 | colonZero() 27 | 28 | if __name__ == '__main__': 29 | main() 30 | raw_input() 31 | -------------------------------------------------------------------------------- /ch13/anyIter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | class AnyIter(object): 4 | def __init__(self, data, safe=0): 5 | self.safe = safe 6 | self.iter = iter(data) 7 | 8 | def __iter__(self): 9 | return self 10 | 11 | def next(self, howmany=1): 12 | retval = [] 13 | for eachItem in range(howmany): 14 | try: 15 | retval.append(self.iter.next()) 16 | except StopIteration: 17 | if self.safe: 18 | break 19 | else: 20 | raise 21 | return retval 22 | -------------------------------------------------------------------------------- /ch18/mtsleep1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import thread 4 | from time import sleep, ctime 5 | 6 | def loop0(): 7 | print 'start loop 0 at:', ctime() 8 | sleep(4) 9 | print 'loop 0 done at:', ctime() 10 | 11 | def loop1(): 12 | print 'start loop 1 at:', ctime() 13 | sleep(2) 14 | print 'loop 1 done at:', ctime() 15 | 16 | def main(): 17 | print 'starting at:', ctime() 18 | thread.start_new_thread(loop0, ()) 19 | thread.start_new_thread(loop1, ()) 20 | sleep(6) 21 | print 'all DONE at:', ctime() 22 | 23 | if __name__ == '__main__': 24 | main() 25 | -------------------------------------------------------------------------------- /ch16/tsTservTW.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from twisted.internet import protocol, reactor 4 | from time import ctime 5 | 6 | PORT = 21567 7 | 8 | class TSServProtocol(protocol.Protocol): 9 | def connectionMade(self): 10 | clnt = self.clnt = self.transport.getPeer().host 11 | print '...connected from:', clnt 12 | def dataReceived(self, data): 13 | self.transport.write('[%s] %s' % ( 14 | ctime(), data)) 15 | 16 | factory = protocol.Factory() 17 | factory.protocol = TSServProtocol 18 | print 'waiting for connection...' 19 | reactor.listenTCP(PORT, factory) 20 | reactor.run() 21 | -------------------------------------------------------------------------------- /ch20/friends.htm: -------------------------------------------------------------------------------- 1 | 2 | Friends CGI Demo (static screen) 3 | 4 |

Friends list for: NEW USER

5 |
6 | Enter your Name: 7 | 8 |

How many friends do you have? 9 | 0 10 | 10 11 | 25 12 | 50 13 | 100 14 |

15 | -------------------------------------------------------------------------------- /ch16/alt/tsUserv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from socket import * 4 | from time import ctime 5 | 6 | HOST = '' 7 | PORT = 21567 8 | BUFSIZ = 1024 9 | ADDR = (HOST, PORT) 10 | 11 | udpSerSock = socket(AF_INET, SOCK_DGRAM) 12 | udpSerSock.setsockopt(SOL_SOCKET, SO_REUSEADDR, True) 13 | udpSerSock.setsockopt(SOL_SOCKET, SO_REUSEPORT, True) 14 | udpSerSock.bind(ADDR) 15 | 16 | while True: 17 | print 'waiting for message...' 18 | data, addr = udpSerSock.recvfrom(BUFSIZ) 19 | udpSerSock.sendto('[%s] %s' % ( 20 | ctime(), data), addr) 21 | print '...received from and returned to:', addr 22 | 23 | udpSerSock.close() 24 | -------------------------------------------------------------------------------- /ch19/tkhello4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from Tkinter import * 4 | 5 | def resize(ev=None): 6 | label.config(font='Helvetica -%d bold' % \ 7 | scale.get()) 8 | 9 | top = Tk() 10 | top.geometry('250x150') 11 | 12 | label = Label(top, text='Hello World!', 13 | font='Helvetica -12 bold') 14 | label.pack(fill=Y, expand=1) 15 | 16 | scale = Scale(top, from_=10, to=40, 17 | orient=HORIZONTAL, command=resize) 18 | scale.set(12) 19 | scale.pack(fill=X, expand=1) 20 | 21 | quit = Button(top, text='QUIT', 22 | command=top.quit, activeforeground='white', 23 | activebackground='red') 24 | quit.pack() 25 | 26 | mainloop() 27 | -------------------------------------------------------------------------------- /ch11/alt/counter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def counter(start_at=0): 4 | count = start_at 5 | while True: 6 | val = (yield count) 7 | if val is not None: 8 | count = val 9 | else: 10 | count += 1 11 | 12 | if __name__ == '__main__': 13 | print 'initializing counter to start counting at 5' 14 | count = counter(5) 15 | print 'calling count.next():', count.next() 16 | print 'calling count.next():', count.next() 17 | print 'calling count.send(9):', count.send(9) 18 | print 'calling count.next():', count.next() 19 | print 'calling count.close():', count.close() 20 | print 'calling count.next():', count.next() 21 | -------------------------------------------------------------------------------- /ch23/stock.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from time import ctime 4 | from urllib import urlopen 5 | 6 | ticks = ('YHOO', 'GOOG', 'EBAY', 'AMZN') 7 | URL = 'http://quote.yahoo.com/d/quotes.csv?s=%s&f=sl1c1p2' 8 | 9 | print '\nPrices quoted as of:', ctime() 10 | print '\nTICKER'.ljust(9), 'PRICE'.ljust(8), 'CHG'.ljust(5), '%AGE' 11 | print '------'.ljust(8), '-----'.ljust(8), '---'.ljust(5), '----' 12 | u = urlopen(URL % ','.join(ticks)) 13 | 14 | for row in u: 15 | tick, price, chg, per = row.split(',') 16 | print eval(tick).ljust(7), \ 17 | ('%.2f' % round(float(price), 2)).rjust(6), \ 18 | chg.rjust(6), eval(per.rstrip()).rjust(6) 19 | 20 | u.close() 21 | -------------------------------------------------------------------------------- /ch06/buggy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # 4 | import string 5 | 6 | # 7 | while 1: 8 | 9 | # 10 | num_str = raw_input('Enter a number: ') 11 | 12 | # 13 | try: 14 | # 15 | num_num = string.atoi(num_str) 16 | 17 | # 18 | break 19 | 20 | # 21 | except ValueError: 22 | print "invalid input... try again" 23 | 24 | # 25 | fac_list = range(1, num_num+1) 26 | print "BEFORE:", `fac_list` 27 | 28 | # 29 | i = 0 30 | 31 | # 32 | while i < len(fac_list): 33 | 34 | # 35 | if num_num % fac_list[i] == 0: 36 | del fac_list[i] 37 | 38 | # 39 | i = i+1 40 | 41 | # 42 | print "AFTER:", `fac_list` 43 | -------------------------------------------------------------------------------- /ch16/tsTserv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from socket import * 4 | from time import ctime 5 | 6 | HOST = '' 7 | PORT = 21567 8 | BUFSIZ = 1024 9 | ADDR = (HOST, PORT) 10 | 11 | tcpSerSock = socket(AF_INET, SOCK_STREAM) 12 | tcpSerSock.bind(ADDR) 13 | tcpSerSock.listen(5) 14 | 15 | while True: 16 | print 'waiting for connection...' 17 | tcpCliSock, addr = tcpSerSock.accept() 18 | print '...connected from:', addr 19 | 20 | while True: 21 | data = tcpCliSock.recv(BUFSIZ) 22 | if not data: 23 | break 24 | tcpCliSock.send('[%s] %s' % ( 25 | ctime(), data)) 26 | 27 | tcpCliSock.close() 28 | tcpSerSock.close() 29 | -------------------------------------------------------------------------------- /ch13/alt/metaIntro.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from time import ctime 4 | 5 | print '*** Welcome to Metaclasses!' 6 | print '\tMetaclass declaration first.' 7 | 8 | class MetaC(type): 9 | def __init__(cls, name, bases, attrd): 10 | super(MetaC, cls).__init__(name, bases, attrd) 11 | print '*** Created class %r at: %s' % ( 12 | name, ctime()) 13 | 14 | print '\tClass "Foo" declaration next.' 15 | 16 | class Foo(object): 17 | __metaclass__ = MetaC 18 | def __init__(self): 19 | print '*** Instantiated class %r at: %s' % ( 20 | self.__class__.__name__, ctime()) 21 | 22 | print '\tClass "Foo" instantiation next.' 23 | f = Foo() 24 | print '\tDONE' 25 | raw_input() 26 | -------------------------------------------------------------------------------- /ch19/alt/tkhello1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id: tkhello1.py,v 1.1 2000/02/21 09:04:25 wesc Exp $ 3 | # 4 | # tkhello1.py -- "Hello World!" 1 in Tkinter: 5 | # - "Hello World!" label (need to close window to quit) 6 | # 7 | # created by wesc 00/02/20 8 | # 9 | 10 | # import Tkinter module 11 | import Tkinter 12 | 13 | # create toplevel window 14 | top = Tkinter.Tk() 15 | 16 | # create label 17 | label = Tkinter.Label(top, text='Hello World!') 18 | 19 | # pack label 20 | label.pack() 21 | 22 | # enter main loop 23 | Tkinter.mainloop() 24 | 25 | """ 26 | same as: 27 | 28 | import Tkinter 29 | Tkinter.Label(Tkinter.Tk(), text='Hello World!').pack() 30 | Tkinter.mainloop() 31 | """ 32 | -------------------------------------------------------------------------------- /ch06/idcheck.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import string 4 | 5 | alphas = string.letters + '_' 6 | nums = string.digits 7 | 8 | print 'Welcome to the Identifier Checker v1.0' 9 | print 'Testees must be at least 2 chars long.' 10 | inp = raw_input('Identifier to test? ') 11 | 12 | if len(inp) > 1: 13 | 14 | if inp[0] not in alphas: 15 | print '''invalid: first symbol must be 16 | alphabetic''' 17 | else: 18 | for otherChar in inp[1:]: 19 | 20 | if otherChar not in alphas + nums: 21 | print '''invalid: remaining 22 | symbols must be alphanumeric''' 23 | break 24 | else: 25 | print "okay as an identifier" 26 | -------------------------------------------------------------------------------- /ch19/animalTix.pyw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from Tkinter import Label, Button, END 4 | from Tix import Tk, Control, ComboBox 5 | 6 | top = Tk() 7 | top.tk.eval('package require Tix') 8 | 9 | lb = Label(top, 10 | text='Animals (in pairs; min: pair, max: dozen)') 11 | lb.pack() 12 | 13 | ct = Control(top, label='Number:', 14 | integer=True, max=12, min=2, value=2, step=2) 15 | ct.label.config(font='Helvetica -14 bold') 16 | ct.pack() 17 | 18 | cb = ComboBox(top, label='Type:', editable=True) 19 | for animal in ('dog', 'cat', 'hamster', 'python'): 20 | cb.insert(END, animal) 21 | cb.pack() 22 | 23 | qb = Button(top, text='QUIT', 24 | command=top.quit, bg='red', fg='white') 25 | qb.pack() 26 | 27 | top.mainloop() 28 | -------------------------------------------------------------------------------- /ch03/makeTextFile0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 'makeTextFile.py -- create text file' 4 | 5 | import os 6 | ls = os.linesep 7 | 8 | # get filename 9 | while True: 10 | 11 | if os.path.exists(fname): 12 | print"*** ERROR: '%s' already exists" % fname 13 | else: 14 | break 15 | 16 | # get file content (text) lines 17 | all = [] 18 | print "\nEnter lines ('.' by itself to quit).\n" 19 | 20 | # loop until user terminates input 21 | while True: 22 | entry = raw_input('> ') 23 | if entry == '.': 24 | break 25 | else: 26 | all.append(entry) 27 | 28 | # write lines to file with proper line-ending 29 | fobj = open(fname, 'w') 30 | fobj.writelines(['%s%s' % (x, ls) for x in all]) 31 | fobj.close() 32 | print 'DONE!' 33 | -------------------------------------------------------------------------------- /ch03/makeTextFile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 'makeTextFile.py -- create text file' 4 | 5 | import os 6 | 7 | # get filename 8 | while True: 9 | fname = raw_input('Enter file name: ') 10 | if os.path.exists(fname): 11 | print"*** ERROR: '%s' already exists" % fname 12 | else: 13 | break 14 | 15 | # get file content (text) lines 16 | all = [] 17 | print "\nEnter lines ('.' by itself to quit).\n" 18 | 19 | # loop until user terminates input 20 | while True: 21 | entry = raw_input('> ') 22 | if entry == '.': 23 | break 24 | else: 25 | all.append(entry) 26 | 27 | # write lines to file with NEWLINE line terminator 28 | fobj = open(fname, 'w') 29 | fobj.write('\n'.join(all)) 30 | fobj.close() 31 | print 'DONE!' 32 | -------------------------------------------------------------------------------- /ch11/grabWeb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from urllib import urlretrieve 4 | 5 | def firstNonBlank(lines): 6 | for eachLine in lines: 7 | if not eachLine.strip(): 8 | continue 9 | else: 10 | return eachLine 11 | 12 | def firstLast(webpage): 13 | f = open(webpage) 14 | lines = f.readlines() 15 | f.close() 16 | print firstNonBlank(lines), 17 | lines.reverse() 18 | print firstNonBlank(lines), 19 | 20 | def download(url='http://www', 21 | process=firstLast): 22 | try: 23 | retval = urlretrieve(url)[0] 24 | except IOError: 25 | retval = None 26 | if retval: # do some processing 27 | process(retval) 28 | 29 | if __name__ == '__main__': 30 | download() 31 | -------------------------------------------------------------------------------- /ch19/animalPmw.pyw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from Tkinter import Button, END, Label, W 4 | from Pmw import initialise, ComboBox, Counter 5 | 6 | top = initialise() 7 | 8 | lb = Label(top, 9 | text='Animals (in pairs; min: pair, max: dozen)') 10 | lb.pack() 11 | 12 | ct = Counter(top, labelpos=W, label_text='Number:', 13 | datatype='integer', entryfield_value=2, 14 | increment=2, entryfield_validate={'validator': 15 | 'integer', 'min': 2, 'max': 12}) 16 | ct.pack() 17 | 18 | cb = ComboBox(top, labelpos=W, label_text='Type:') 19 | for animal in ('dog', 'cat', 'hamster', 'python'): 20 | cb.insert(END, animal) 21 | cb.pack() 22 | 23 | qb = Button(top, text='QUIT', 24 | command=top.quit, bg='red', fg='white') 25 | qb.pack() 26 | 27 | top.mainloop() 28 | -------------------------------------------------------------------------------- /ch03/makeTextFile.diff: -------------------------------------------------------------------------------- 1 | --- makeTextFile.py 2006-01-29 21:29:44.000000000 -0700 2 | +++ makeTextFile-fix.py 2006-10-11 21:49:35.000000000 -0700 3 | @@ -3,11 +3,10 @@ 4 | 'makeTextFile.py -- create text file' 5 | 6 | import os 7 | -ls = os.linesep 8 | 9 | # get filename 10 | while True: 11 | - 12 | + fname = raw_input('Enter file name: ') 13 | if os.path.exists(fname): 14 | print"*** ERROR: '%s' already exists" % fname 15 | else: 16 | @@ -25,8 +24,8 @@ 17 | else: 18 | all.append(entry) 19 | 20 | -# write lines to file with proper line-ending 21 | +# write lines to file with NEWLINE line terminator 22 | fobj = open(fname, 'w') 23 | -fobj.writelines(['%s%s' % (x, ls) for x in all]) 24 | +fobj.write('\n'.join(all)) 25 | fobj.close() 26 | print 'DONE!' 27 | -------------------------------------------------------------------------------- /ch14/funcAttrs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def foo(): 4 | return True 5 | 6 | def bar(): 7 | 'bar() does not do much' 8 | return True 9 | 10 | foo.__doc__ = 'foo() does not do much' 11 | foo.tester = ''' 12 | if foo(): 13 | print 'PASSED' 14 | else: 15 | print 'FAILED' 16 | ''' 17 | 18 | for eachAttr in dir(): 19 | obj = eval(eachAttr) 20 | if isinstance(obj, type(foo)): 21 | if hasattr(obj, '__doc__'): 22 | print '\nFunction "%s" has a doc string:\n\t%s' % (eachAttr, obj.__doc__) 23 | if hasattr(obj, 'tester'): 24 | print 'Function "%s" has a tester... executing' % eachAttr 25 | exec obj.tester 26 | else: 27 | print 'Function "%s" has no tester... skipping' % eachAttr 28 | else: 29 | print '"%s" is not a function' % eachAttr 30 | -------------------------------------------------------------------------------- /ch13/time60.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | class Time60(object): 4 | 'Time60 - track hours and minutes' 5 | 6 | def __init__(self, hr, min): 7 | 'Time60 initializer - takes hours and minutes' 8 | self.hr = hr 9 | self.min = min 10 | 11 | def __str__(self): 12 | 'Time60 - string representation' 13 | return '%d:%d' % (self.hr, self.min) 14 | 15 | __repr__ = __str__ 16 | 17 | def __add__(self, other): 18 | 'Time60 - overloading the addition operator' 19 | return self.__class__(self.hr + other.hr, 20 | self.min + other.min) 21 | 22 | def __iadd__(self, other): 23 | 'Time60 - overloading in-place addition' 24 | self.hr += other.hr 25 | self.min += other.min 26 | return self 27 | -------------------------------------------------------------------------------- /ch16/alt/tsTserv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from socket import * 4 | from time import ctime 5 | 6 | HOST = '' 7 | PORT = 21567 8 | BUFSIZ = 1024 9 | ADDR = (HOST, PORT) 10 | 11 | tcpSerSock = socket(AF_INET, SOCK_STREAM) 12 | tcpSerSock.setsockopt(SOL_SOCKET, SO_REUSEADDR, True) 13 | tcpSerSock.setsockopt(SOL_SOCKET, SO_REUSEPORT, True) 14 | tcpSerSock.bind(ADDR) 15 | tcpSerSock.listen(5) 16 | 17 | while True: 18 | print 'waiting for connection...' 19 | tcpCliSock, addr = tcpSerSock.accept() 20 | print '...connected from:', addr 21 | 22 | while True: 23 | data = tcpCliSock.recv(BUFSIZ) 24 | if not data: 25 | break 26 | tcpCliSock.send('[%s] %s' % ( 27 | ctime(), data)) 28 | 29 | tcpCliSock.close() 30 | tcpSerSock.close() 31 | -------------------------------------------------------------------------------- /ch13/moneyfmt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | class MoneyFmt(object): 4 | def __init__(self, value=0.0): # constructor 5 | self.value = float(value) 6 | 7 | def update(self, value=None): # allow updates 8 | ### 9 | ### (a) complete this function 10 | ### 11 | 12 | def __repr__(self): # display as a float 13 | return `self.value` 14 | 15 | def __str__(self): # formatted display 16 | val = '' 17 | 18 | ### 19 | ### (b) complete this function... do NOT 20 | ### forget about negative numbers too!! 21 | ### 22 | 23 | return val 24 | 25 | def __nonzero__(self): # boolean test 26 | ### 27 | ### (c) find and fix the bug 28 | ### 29 | 30 | return int(self.value) 31 | -------------------------------------------------------------------------------- /ch03/makeTextFile1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 'makeTextFile.py -- create text file' 4 | 5 | import os 6 | ls = os.linesep 7 | 8 | # get filename 9 | while True: 10 | fname = raw_input('Enter file name: ') 11 | if os.path.exists(fname): 12 | print"*** ERROR: '%s' already exists" % fname 13 | else: 14 | break 15 | 16 | # get file content (text) lines 17 | all = [] 18 | print "\nEnter lines ('.' by itself to quit).\n" 19 | 20 | # loop until user terminates input 21 | while True: 22 | entry = raw_input('> ') 23 | if entry == '.': 24 | break 25 | else: 26 | all.append(entry) 27 | 28 | # write lines to file with proper line-ending 29 | fobj = open(fname, 'w') 30 | fobj.writelines(['%s%s' % (x, ls) for x in all]) 31 | fobj.close() 32 | print 'DONE!' 33 | -------------------------------------------------------------------------------- /ch13/ProtectAndHideX.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 'ProtectAndHideX.py -- protect the "x" attribute' 3 | 4 | class ProtectAndHideX(object): 5 | def __init__(self, x): 6 | self.x = x 7 | 8 | def x(): 9 | def fget(self): 10 | return ~self.__x 11 | 12 | def fset(self, x): 13 | assert isinstance(x, int), \ 14 | '"x" must be an integer!' 15 | self.__x = ~x 16 | 17 | return locals() 18 | 19 | x = property(**x()) 20 | 21 | inst = ProtectAndHideX(10) 22 | print 'inst.x has a value of:', inst.x 23 | inst.x = 20 24 | print 'inst.x has a value of:', inst.x 25 | #inst.fset(40) # sorry! 26 | #print 'inst.x has a value of:', inst.x 27 | inst.x.fset(40) # sorry! 28 | print 'inst.x has a value of:', inst.x 29 | -------------------------------------------------------------------------------- /ch15/gendata.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from random import randint, choice 4 | from string import lowercase 5 | from sys import maxint 6 | from time import ctime 7 | 8 | doms = ( 'com', 'edu', 'net', 'org', 'gov' ) 9 | 10 | for i in range(randint(5, 10)): 11 | dtint = randint(0, maxint-1) # pick date 12 | dtstr = ctime(dtint) # date string 13 | 14 | shorter = randint(4, 7) # login shorter 15 | em = '' 16 | for j in range(shorter): # generate login 17 | em += choice(lowercase) 18 | 19 | longer = randint(shorter, 12) # domain longer 20 | dn = '' 21 | for j in range(longer): # create domain 22 | dn += choice(lowercase) 23 | 24 | print '%s::%s@%s.%s::%d-%d-%d' % (dtstr, em, 25 | dn, choice(doms), dtint, shorter, longer) 26 | -------------------------------------------------------------------------------- /ch18/mtsleep3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import threading 4 | from time import sleep, ctime 5 | 6 | loops = [ 4, 2 ] 7 | 8 | def loop(nloop, nsec): 9 | print 'start loop', nloop, 'at:', ctime() 10 | sleep(nsec) 11 | print 'loop', nloop, 'done at:', ctime() 12 | 13 | def main(): 14 | print 'starting at:', ctime() 15 | threads = [] 16 | nloops = range(len(loops)) 17 | 18 | for i in nloops: 19 | t = threading.Thread(target=loop, 20 | args=(i, loops[i])) 21 | threads.append(t) 22 | 23 | for i in nloops: # start threads 24 | threads[i].start() 25 | 26 | for i in nloops: # wait for all 27 | threads[i].join() # threads to finish 28 | 29 | print 'all DONE at:', ctime() 30 | 31 | if __name__ == '__main__': 32 | main() 33 | -------------------------------------------------------------------------------- /ch18/mtsleep2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import thread 4 | from time import sleep, ctime 5 | 6 | loops = [4, 2] 7 | 8 | def loop(nloop, nsec, lock): 9 | print 'start loop', nloop, 'at:', ctime() 10 | sleep(nsec) 11 | print 'loop', nloop, 'done at:', ctime() 12 | lock.release() 13 | 14 | def main(): 15 | print 'starting threads...' 16 | locks = [] 17 | nloops = range(len(loops)) 18 | 19 | for i in nloops: 20 | lock = thread.allocate_lock() 21 | lock.acquire() 22 | locks.append(lock) 23 | 24 | for i in nloops: 25 | thread.start_new_thread(loop, 26 | (i, loops[i], locks[i])) 27 | 28 | for i in nloops: 29 | while locks[i].locked(): pass 30 | 31 | print 'all DONE at:', ctime() 32 | 33 | if __name__ == '__main__': 34 | main() 35 | -------------------------------------------------------------------------------- /ch16/alt/tsTservNew.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from socket import * 4 | from time import ctime 5 | 6 | HOST = '' 7 | PORT = 21567 8 | BUFSIZ = 1024 9 | ADDR = (HOST, PORT) 10 | 11 | tcpSerSock = socket(AF_INET, SOCK_STREAM) 12 | tcpSerSock.setsockopt(SOL_SOCKET, SO_REUSEADDR, True) 13 | tcpSerSock.setsockopt(SOL_SOCKET, SO_REUSEPORT, True) 14 | tcpSerSock.bind(ADDR) 15 | tcpSerSock.listen(5) 16 | 17 | while True: 18 | print 'waiting for connection...' 19 | tcpCliSock, addr = tcpSerSock.accept() 20 | print '...connected from:', addr 21 | 22 | while True: 23 | data = tcpCliSock.recv(BUFSIZ) 24 | if not data: 25 | break 26 | print data 27 | data = raw_input('> ') 28 | if not data: 29 | break 30 | tcpCliSock.send(data) 31 | print " ... waiting for reply ..." 32 | 33 | tcpCliSock.close() 34 | tcpSerSock.close() 35 | -------------------------------------------------------------------------------- /ch11/testit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def testit(func, *nkwargs, **kwargs): 4 | 5 | try: 6 | retval = func(*nkwargs, **kwargs) 7 | result = (True, retval) 8 | except Exception, diag: 9 | result = (False, str(diag)) 10 | return result 11 | 12 | def test(): 13 | funcs = (int, long, float) 14 | vals = (1234, 12.34, '1234', '12.34') 15 | 16 | for eachFunc in funcs: 17 | print '-' * 20 18 | for eachVal in vals: 19 | retval = testit(eachFunc, 20 | eachVal) 21 | if retval[0]: 22 | print '%s(%s) =' % \ 23 | (eachFunc.__name__, `eachVal`), retval[1] 24 | else: 25 | print '%s(%s) = FAILED:' % \ 26 | (eachFunc.__name__, `eachVal`), retval[1] 27 | 28 | if __name__ == '__main__': 29 | test() 30 | -------------------------------------------------------------------------------- /ch23/excel.pyw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from Tkinter import Tk 4 | from time import sleep 5 | from tkMessageBox import showwarning 6 | import win32com.client as win32 7 | 8 | warn = lambda app: showwarning(app, 'Exit?') 9 | RANGE = range(3, 8) 10 | 11 | def excel(): 12 | app = 'Excel' 13 | xl = win32.gencache.EnsureDispatch('%s.Application' % app) 14 | ss = xl.Workbooks.Add() 15 | sh = ss.ActiveSheet 16 | xl.Visible = True 17 | sleep(1) 18 | 19 | sh.Cells(1,1).Value = 'Python-to-%s Demo' % app 20 | sleep(1) 21 | for i in RANGE: 22 | sh.Cells(i,1).Value = 'Line %d' % i 23 | sleep(1) 24 | sh.Cells(i+2,1).Value = "Th-th-th-that's all folks!" 25 | 26 | warn(app) 27 | ss.Close(False) 28 | xl.Application.Quit() 29 | 30 | if __name__=='__main__': 31 | Tk().withdraw() 32 | excel() 33 | -------------------------------------------------------------------------------- /ch23/word.pyw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from Tkinter import Tk 4 | from time import sleep 5 | from tkMessageBox import showwarning 6 | import win32com.client as win32 7 | 8 | warn = lambda app: showwarning(app, 'Exit?') 9 | RANGE = range(3, 8) 10 | 11 | def word(): 12 | app = 'Word' 13 | word = win32.gencache.EnsureDispatch('%s.Application' % app) 14 | doc = word.Documents.Add() 15 | word.Visible = True 16 | sleep(1) 17 | 18 | rng = doc.Range(0,0) 19 | rng.InsertAfter('Python-to-%s Test\r\n\r\n' % app) 20 | sleep(1) 21 | for i in RANGE: 22 | rng.InsertAfter('Line %d\r\n' % i) 23 | sleep(1) 24 | rng.InsertAfter("\r\nTh-th-th-that's all folks!\r\n") 25 | 26 | warn(app) 27 | doc.Close(False) 28 | word.Application.Quit() 29 | 30 | if __name__=='__main__': 31 | Tk().withdraw() 32 | word() 33 | -------------------------------------------------------------------------------- /ch13/alt/anyIter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | class AnyIter: # any number of items iterator 4 | def __init__(self, data, safe=0): 5 | self.safe = safe # play it safe 6 | self.iter = iter(data) # our iterator 7 | 8 | def __iter__(self): # class iterator 9 | return self 10 | 11 | def next(self, howmany=1): # special next() 12 | retval = [] 13 | for eachItem in range(howmany): 14 | try: 15 | retval.append(self.iter.next()) 16 | except StopIteration: 17 | # reraise if asking for too 18 | # many items 19 | if self.safe == 0: 20 | raise 21 | # "safe" mode: return less than 22 | # requested 23 | else: 24 | break 25 | return retval 26 | -------------------------------------------------------------------------------- /ch16/tsTclntTW.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from twisted.internet import protocol, reactor 4 | 5 | HOST = 'localhost' 6 | PORT = 21567 7 | 8 | class TSClntProtocol(protocol.Protocol): 9 | def sendData(self): 10 | data = raw_input('> ') 11 | if data: 12 | print '...sending %s...' % data 13 | self.transport.write(data) 14 | else: 15 | self.transport.loseConnection() 16 | 17 | def connectionMade(self): 18 | self.sendData() 19 | 20 | def dataReceived(self, data): 21 | print data 22 | self.sendData() 23 | 24 | class TSClntFactory(protocol.ClientFactory): 25 | protocol = TSClntProtocol 26 | clientConnectionLost = clientConnectionFailed = \ 27 | lambda self, connector, reason: reactor.stop() 28 | 29 | reactor.connectTCP(HOST, PORT, TSClntFactory()) 30 | reactor.run() 31 | -------------------------------------------------------------------------------- /ch06/alt/idcheck2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from keyword import kwlist 4 | import string 5 | 6 | ALPHAS = string.ascii_letters + '_' 7 | NUMS = string.digits 8 | 9 | def main(): 10 | print 'Welcome to the Identifier Checker v2.0' 11 | myInput = raw_input('Identifier to test? ').strip() 12 | 13 | if len(myInput) == 0: 14 | print "ERROR: no identifier candidate entered" 15 | return 16 | 17 | if myInput in kwlist: 18 | print "ERROR: %r is a keyword" % myInput 19 | return 20 | 21 | alnums = ALPHAS + NUMS 22 | for i, c in enumerate(myInput): 23 | if i == 0 and c not in ALPHAS: 24 | print 'ERROR: first symbol must be alphabetic' 25 | break 26 | if c not in alnums: 27 | print 'ERROR: remaining symbols must be alphanumeric' 28 | break 29 | else: 30 | print "okay as an identifier" 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /ch13/alt/hotel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | class HotelRoomCalc: 4 | 'Hotel room rate calculator' 5 | 6 | # constructor, set default sales and room tax rates 7 | def __init__(self, rt, sales=0.085, rm=0.1): 8 | 'HotelRoolCalc default args: sales tax == 8.5% & room tax == 10%' 9 | self.salesTax = sales # set sales tax rate 10 | self.roomTax = rm # set room tax rate 11 | self.roomRate = rt # set daily room rate 12 | 13 | # calculate total due, defaulting to a 1-day stay 14 | def calcTotal(self, days=1): 15 | 'Calculate total; default to daily rate' 16 | 17 | # calculate total... take room rate, add sales 18 | # and room taxes and round to 2 decimal places 19 | daily = round((self.roomRate * (1 + self.roomTax + self.salesTax)), 2) 20 | 21 | # now multiply by length of stay and return 22 | return float(days) * daily 23 | -------------------------------------------------------------------------------- /ch13/alt/capOpen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id: capOpen.py,v 1.1 2000/07/01 23:10:01 wesc Exp $ 3 | # 4 | # capOpen.py -- short delegation example with files 5 | # 6 | # created on 00/06/01 by wesc 7 | # 8 | 9 | from string import upper # import string.upper() 10 | 11 | class capOpen: 12 | 13 | # constructor 14 | def __init__(self, fn, mode='r', buf=-1): 15 | self.file = open(fn, mode, buf) 16 | 17 | # str() calls this 18 | def __str__(self): 19 | return str(self.file) 20 | 21 | # repr() and `` call this 22 | def __repr__(self): 23 | return `self.file` 24 | 25 | # implement/override write() (which calls the real write()) 26 | def write(self, line): 27 | self.file.write(upper(line)) 28 | 29 | # delegation happens here, i.e., delegate all other methods 30 | def __getattr__(self, attr): 31 | return getattr(self.file, attr) 32 | -------------------------------------------------------------------------------- /ch20/alt/friends1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id: friends1.py,v 1.1 2000/12/31 01:32:45 wesc Exp $ 4 | 5 | Friends CGI demo 6 | ''' 7 | 8 | import cgi 9 | from string import atoi,replace 10 | 11 | reshtml = '''Content-Type: text/html\n 12 | Friends CGI Demo (dynamic screen) 13 |

Friends list for: %s

14 | Your name is: %s

15 | You have %s friends. 16 | ''' 17 | 18 | # process() does all the work 19 | def process(): 20 | 21 | # initialize Data class object 22 | form = cgi.FieldStorage() 23 | 24 | # get name and number of friends 25 | who = form['person'].value 26 | howmany = form['howmany'].value 27 | 28 | # substitute in real name and number of friends and return 29 | print reshtml % (who, who, howmany) 30 | 31 | # invoke if called directly 32 | if __name__ == '__main__': 33 | process() 34 | -------------------------------------------------------------------------------- /ch20/urlopenAuth.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import urllib2 4 | 5 | LOGIN = 'wesley' 6 | PASSWD = "you'llNeverGuess" 7 | URL = 'http://localhost' 8 | 9 | def handler_version(url): 10 | from urlparse import urlparse as up 11 | hdlr = urllib2.HTTPBasicAuthHandler() 12 | hdlr.add_password('Archives', up(url)[1], LOGIN, PASSWD) 13 | opener = urllib2.build_opener(hdlr) 14 | urllib2.install_opener(opener) 15 | return url 16 | 17 | def request_version(url): 18 | from base64 import encodestring 19 | req = urllib2.Request(url) 20 | b64str = encodestring('%s:%s' % (LOGIN, PASSWD))[:-1] 21 | req.add_header("Authorization", "Basic %s" % b64str) 22 | return req 23 | 24 | for funcType in ('handler', 'request'): 25 | print '*** Using %s:' % funcType.upper() 26 | url = eval('%s_version')(URL) 27 | f = urllib2.urlopen(url) 28 | print f.readline() 29 | f.close() 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # PyInstaller 26 | # Usually these files are written by a python script from a template 27 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 28 | *.manifest 29 | *.spec 30 | 31 | # Installer logs 32 | pip-log.txt 33 | pip-delete-this-directory.txt 34 | 35 | # Unit test / coverage reports 36 | htmlcov/ 37 | .tox/ 38 | .coverage 39 | .cache 40 | nosetests.xml 41 | coverage.xml 42 | 43 | # Translations 44 | *.mo 45 | *.pot 46 | 47 | # Django stuff: 48 | *.log 49 | 50 | # Sphinx documentation 51 | docs/_build/ 52 | 53 | # PyBuilder 54 | target/ 55 | -------------------------------------------------------------------------------- /ch13/descrPRE25.diff: -------------------------------------------------------------------------------- 1 | --- descr.py 2006-04-10 17:42:53.000000000 -0700 2 | +++ descrPRE25.py 2006-10-11 22:26:43.000000000 -0700 3 | @@ -6,7 +6,7 @@ 4 | class FileDescr(object): 5 | saved = [] 6 | 7 | - def __init__(self, name=None): 8 | + def __init__(self, name): 9 | self.name = name 10 | 11 | def __get__(self, obj, typ=None): 12 | @@ -26,12 +26,12 @@ 13 | "could not read %r: %s" % self.name 14 | 15 | def __set__(self, obj, val): 16 | - f = open(self.name, 'w') 17 | try: 18 | try: 19 | + f = open(self.name, 'w') 20 | pickle.dump(val, f) 21 | FileDescr.saved.append(self.name) 22 | - except (TypeError, pickle.PicklingError), e: 23 | + except (IOError, TypeError, pickle.PicklingError), e: 24 | raise AttributeError, \ 25 | "could not pickle %r" % self.name 26 | finally: 27 | -------------------------------------------------------------------------------- /ch17/myMail.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from smtplib import SMTP 4 | from poplib import POP3 5 | from time import sleep 6 | 7 | SMTPSVR = 'smtp.python.is.cool' 8 | POP3SVR = 'pop.python.is.cool' 9 | 10 | origHdrs = ['From: wesley@python.is.cool', 11 | 'To: wesley@python.is.cool', 12 | 'Subject: test msg'] 13 | origBody = ['xxx', 'yyy', 'zzz'] 14 | origMsg = '\r\n\r\n'.join(['\r\n'.join(origHdrs), '\r\n'.join(origBody)]) 15 | 16 | sendSvr = SMTP(SMTPSVR) 17 | errs = sendSvr.sendmail('wesley@python.is.cool', 18 | ('wesley@python.is.cool', ), origMsg) 19 | sendSvr.quit() 20 | assert len(errs) == 0, errs 21 | sleep(10) # wait for mail to be delivered 22 | 23 | recvSvr = POP3(POP3SVR) 24 | recvSvr.user('wesley') 25 | recvSvr.pass_('youllNeverGuess') 26 | rsp, msg, siz = recvSvr.retr(recvSvr.stat()[0]) 27 | # strip headers and compare to orig msg 28 | sep = msg.index('') 29 | recvBody = msg[sep+1:] 30 | assert origBody == recvBody # assert identical 31 | -------------------------------------------------------------------------------- /ch11/closureVars.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | output = '' 4 | w = x = y = z = 1 5 | 6 | def f1(): 7 | x = y = z = 2 8 | 9 | def f2(): 10 | y = z = 3 11 | 12 | def f3(): 13 | z = 4 14 | print output % ('w', id(w), w) 15 | print output % ('x', id(x), x) 16 | print output % ('y', id(y), y) 17 | print output % ('z', id(z), z) 18 | 19 | clo = f3.func_closure 20 | if clo: 21 | print "f3 closure vars:", [str(c) for c in clo] 22 | else: 23 | print "no f3 closure vars" 24 | f3() 25 | 26 | clo = f2.func_closure 27 | if clo: 28 | print "f2 closure vars:", [str(c) for c in clo] 29 | else: 30 | print "no f2 closure vars" 31 | f2() 32 | 33 | clo = f1.func_closure 34 | if clo: 35 | print "f1 closure vars:", [str(c) for c in clo] 36 | else: 37 | print "no f1 closure vars" 38 | f1() 39 | -------------------------------------------------------------------------------- /ch23/ppoint.pyw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from Tkinter import Tk 4 | from time import sleep 5 | from tkMessageBox import showwarning 6 | import win32com.client as win32 7 | 8 | warn = lambda app: showwarning(app, 'Exit?') 9 | RANGE = range(3, 8) 10 | 11 | def ppoint(): 12 | app = 'PowerPoint' 13 | ppoint = win32.gencache.EnsureDispatch('%s.Application' % app) 14 | pres = ppoint.Presentations.Add() 15 | ppoint.Visible = True 16 | 17 | s1 = pres.Slides.Add(1, win32.constants.ppLayoutText) 18 | sleep(1) 19 | s1a = s1.Shapes[0].TextFrame.TextRange 20 | s1a.Text = 'Python-to-%s Demo' % app 21 | sleep(1) 22 | s1b = s1.Shapes[1].TextFrame.TextRange 23 | for i in RANGE: 24 | s1b.InsertAfter("Line %d\r\n" % i) 25 | sleep(1) 26 | s1b.InsertAfter("\r\nTh-th-th-that's all folks!") 27 | 28 | warn(app) 29 | pres.Close() 30 | ppoint.Quit() 31 | 32 | if __name__=='__main__': 33 | Tk().withdraw() 34 | ppoint() 35 | -------------------------------------------------------------------------------- /ch20/myhttpd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from os import curdir, sep 4 | from BaseHTTPServer import \ 5 | BaseHTTPRequestHandler, HTTPServer 6 | 7 | class MyHandler(BaseHTTPRequestHandler): 8 | 9 | def do_GET(self): 10 | try: 11 | f = open(curdir + sep + self.path) 12 | self.send_response(200) 13 | self.send_header('Content-type', 14 | 'text/html') 15 | self.end_headers() 16 | self.wfile.write(f.read()) 17 | f.close() 18 | except IOError: 19 | self.send_error(404, 20 | 'File Not Found: %s' % self.path) 21 | 22 | def main(): 23 | try: 24 | server = HTTPServer(('', 80), MyHandler) 25 | print 'Welcome to the machine...' 26 | print 'Press ^C once or twice to quit' 27 | server.serve_forever() 28 | except KeyboardInterrupt: 29 | print '^C received, shutting down server' 30 | server.socket.close() 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /ch10/cardrun.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def safe_float(object): 4 | 'safe version of float()' 5 | try: 6 | retval = float(object) 7 | except (TypeError, ValueError), diag: 8 | retval = str(diag) 9 | return retval 10 | 11 | def main(): 12 | 'handles all the data processing' 13 | log = open('cardlog.txt', 'w') 14 | try: 15 | ccfile = open('carddata.txt', 'r') 16 | except IOError, e: 17 | log.write('no txns this month\n') 18 | log.close() 19 | return 20 | 21 | txns = ccfile.readlines() 22 | ccfile.close() 23 | total = 0.00 24 | log.write('account log:\n') 25 | 26 | for eachTxn in txns: 27 | result = safe_float(eachTxn) 28 | if isinstance(result, float): 29 | total += result 30 | log.write('data... processed\n') 31 | else: 32 | log.write('ignored: %s' % result) 33 | print '$%.2f (new balance)' % (total) 34 | log.close() 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /ch11/funcLog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from time import time 4 | 5 | def logged(when): 6 | def log(f, *args, **kargs): 7 | print """Called: 8 | function: %s 9 | args: %r 10 | kargs: %r""" % (f, args, kargs) 11 | 12 | def pre_logged(f): 13 | def wrapper(*args, **kargs): 14 | log(f, *args, **kargs) 15 | return f(*args, **kargs) 16 | return wrapper 17 | 18 | def post_logged(f): 19 | def wrapper(*args, **kargs): 20 | now = time() 21 | try: 22 | return f(*args, **kargs) 23 | finally: 24 | log(f, *args, **kargs) 25 | print " time delta: %s" % (time()-now) 26 | return wrapper 27 | 28 | try: 29 | return {"pre": pre_logged, 30 | "post": post_logged}[when] 31 | except KeyError, e: 32 | raise ValueError(e), 'must be "pre" or "post"' 33 | 34 | @logged("post") 35 | def hello(name): 36 | print "Hello,", name 37 | 38 | hello("World!") 39 | -------------------------------------------------------------------------------- /ch22/Extest1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int fac(int n) 6 | { 7 | if (n < 2) return(1); /* 0! == 1! == 1 */ 8 | return (n)*fac(n-1); /* n! == n*(n-1)! */ 9 | } 10 | 11 | char *reverse(char *s) 12 | { 13 | register char t, /* tmp */ 14 | *p = s, /* fwd */ 15 | *q = (s + (strlen(s) - 1)); /* bwd */ 16 | 17 | while (p < q) /* if p < q */ 18 | { 19 | t = *p; /* swap & move ptrs */ 20 | *p++ = *q; 21 | *q-- = t; 22 | } 23 | return(s); 24 | } 25 | 26 | int main() 27 | { 28 | char s[BUFSIZ]; 29 | printf("4! == %d\n", fac(4)); 30 | printf("8! == %d\n", fac(8)); 31 | printf("12! == %d\n", fac(12)); 32 | strcpy(s, "abcdef"); 33 | printf("reversing 'abcdef', we get '%s'\n", \ 34 | reverse(s)); 35 | strcpy(s, "madam"); 36 | printf("reversing 'madam', we get '%s'\n", \ 37 | reverse(s)); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /ch18/mtsleep5.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import threading 4 | from time import sleep, ctime 5 | 6 | loops = [ 4, 2 ] 7 | 8 | class MyThread(threading.Thread): 9 | def __init__(self, func, args, name=''): 10 | threading.Thread.__init__(self) 11 | self.name = name 12 | self.func = func 13 | self.args = args 14 | 15 | def run(self): 16 | apply(self.func, self.args) 17 | 18 | def loop(nloop, nsec): 19 | print 'start loop', nloop, 'at:', ctime() 20 | sleep(nsec) 21 | print 'loop', nloop, 'done at:', ctime() 22 | 23 | def main(): 24 | print 'starting at:', ctime() 25 | threads = [] 26 | nloops = range(len(loops)) 27 | 28 | for i in nloops: 29 | t = MyThread(loop, (i, loops[i]), 30 | loop.__name__) 31 | threads.append(t) 32 | 33 | for i in nloops: 34 | threads[i].start() 35 | 36 | for i in nloops: 37 | threads[i].join() 38 | 39 | print 'all DONE at:', ctime() 40 | 41 | if __name__ == '__main__': 42 | main() 43 | -------------------------------------------------------------------------------- /ch23/olook.pyw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from Tkinter import Tk 4 | #from time import sleep # SUPERFLUOUS 5 | from tkMessageBox import showwarning 6 | import win32com.client as win32 7 | 8 | warn = lambda app: showwarning(app, 'Exit?') 9 | RANGE = range(3, 8) 10 | 11 | def outlook(): 12 | app = 'Outlook' 13 | olook = win32.gencache.EnsureDispatch('%s.Application' % app) 14 | 15 | mail = olook.CreateItem(win32.constants.olMailItem) 16 | recip = mail.Recipients.Add('you@127.0.0.1') 17 | subj = mail.Subject = 'Python-to-%s Demo' % app 18 | body = ["Line %d" % i for i in RANGE] 19 | body.insert(0, '%s\r\n' % subj) 20 | body.append("\r\nTh-th-th-that's all folks!") 21 | mail.Body = '\r\n'.join(body) 22 | mail.Send() 23 | 24 | ns = olook.GetNamespace("MAPI") 25 | obox = ns.GetDefaultFolder(win32.constants.olFolderOutbox) 26 | obox.Display() 27 | obox.Items.Item(1).Display() 28 | 29 | warn(app) 30 | olook.Quit() 31 | olook = outlook 32 | 33 | if __name__=='__main__': 34 | Tk().withdraw() 35 | outlook() 36 | -------------------------------------------------------------------------------- /ch19/alt/tkhello4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id: tkhello4.py,v 1.2 2000/02/21 10:56:50 wesc Exp $ 3 | # 4 | # tkhello4.py -- "Hello World!" 4 in Tkinter: 5 | # - label, button, and scale widgets 6 | # 7 | # created by wesc 00/02/21 8 | # 9 | 10 | # import all Tkinter module attributes 11 | from Tkinter import * 12 | 13 | # callback function to resize label when Scale is slid 14 | def resize(ev=None): 15 | label.config(font='Helvetica -%d bold' % scale.get()) 16 | 17 | # create toplevel window with a 250x150 pixel geometry 18 | top = Tk() 19 | top.geometry('250x150') 20 | 21 | # create and pack label 22 | label = Label(top, text='Hello World!', font='Helvetica -12 bold') 23 | label.pack(fill=Y, expand=1) 24 | 25 | # create and pack Scale/slider 26 | scale = Scale(top, from_=10, to=40, orient=HORIZONTAL, command=resize) 27 | scale.set(12) 28 | scale.pack(fill=X, expand=1) 29 | 30 | # create and pack button 31 | quit = Button(top, text='QUIT', command=top.quit, activeforeground='white', activebackground='red') 32 | quit.pack() 33 | 34 | # enter main loop 35 | mainloop() 36 | -------------------------------------------------------------------------------- /ch18/mtsleep4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import threading 4 | from time import sleep, ctime 5 | 6 | loops = [ 4, 2 ] 7 | 8 | class ThreadFunc(object): 9 | 10 | def __init__(self, func, args, name=''): 11 | self.name = name 12 | self.func = func 13 | self.args = args 14 | 15 | def __call__(self): 16 | apply(self.func, self.args) 17 | 18 | def loop(nloop, nsec): 19 | print 'start loop', nloop, 'at:', ctime() 20 | sleep(nsec) 21 | print 'loop', nloop, 'done at:', ctime() 22 | 23 | def main(): 24 | print 'starting at:', ctime() 25 | threads = [] 26 | nloops = range(len(loops)) 27 | 28 | for i in nloops: # create all threads 29 | t = threading.Thread( 30 | target=ThreadFunc(loop, (i, loops[i]), 31 | loop.__name__)) 32 | threads.append(t) 33 | 34 | for i in nloops: # start all threads 35 | threads[i].start() 36 | 37 | for i in nloops: # wait for completion 38 | threads[i].join() 39 | 40 | print 'all DONE at:', ctime() 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /ch13/descr.diff: -------------------------------------------------------------------------------- 1 | --- descr.py 2006-04-10 17:42:53.000000000 -0700 2 | +++ descr-fix.py 2006-10-11 22:27:10.000000000 -0700 3 | @@ -6,7 +6,7 @@ 4 | class FileDescr(object): 5 | saved = [] 6 | 7 | - def __init__(self, name=None): 8 | + def __init__(self, name): 9 | self.name = name 10 | 11 | def __get__(self, obj, typ=None): 12 | @@ -26,14 +26,13 @@ 13 | "could not read %r: %s" % self.name 14 | 15 | def __set__(self, obj, val): 16 | - f = open(self.name, 'w') 17 | try: 18 | - try: 19 | - pickle.dump(val, f) 20 | - FileDescr.saved.append(self.name) 21 | - except (TypeError, pickle.PicklingError), e: 22 | - raise AttributeError, \ 23 | - "could not pickle %r" % self.name 24 | + f = open(self.name, 'w') 25 | + pickle.dump(val, f) 26 | + FileDescr.saved.append(self.name) 27 | + except (IOError, TypeError, pickle.PicklingError), e: 28 | + raise AttributeError, \ 29 | + "could not pickle %r" % self.name 30 | finally: 31 | f.close() 32 | 33 | -------------------------------------------------------------------------------- /ch06/queue.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | queue = [] 4 | 5 | def enQ(): 6 | queue.append(raw_input('Enter new queue element: ')) 7 | 8 | def deQ(): 9 | if len(queue) == 0: 10 | print 'Cannot dequeue from empty queue!' 11 | else: 12 | print 'Removed [', queue.pop(0), ']' 13 | 14 | def viewQ(): 15 | print str(queue) 16 | 17 | def showmenu(): 18 | prompt = """ 19 | (E)nqueue 20 | (D)equeue 21 | (V)iew 22 | (Q)uit 23 | 24 | Enter choice: """ 25 | 26 | done = 0 27 | while not done: 28 | 29 | chosen = 0 30 | while not chosen: 31 | try: 32 | choice = raw_input(prompt)[0] 33 | except (IndexError, EOFError, KeyboardInterrupt): 34 | choice = 'q' 35 | print '\nYou picked: [%s]' % choice 36 | if choice not in 'devq': 37 | print 'invalid option, try again' 38 | else: 39 | chosen = 1 40 | 41 | if choice == 'q': done = 1 42 | if choice == 'e': enQ() 43 | if choice == 'd': deQ() 44 | if choice == 'v': viewQ() 45 | 46 | if __name__ == '__main__': 47 | showmenu() 48 | -------------------------------------------------------------------------------- /ch06/stack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | stack = [] 4 | 5 | def pushit(): 6 | stack.append(raw_input('Enter new string: ')) 7 | 8 | def popit(): 9 | if len(stack) == 0: 10 | print 'Cannot pop from an empty stack!' 11 | else: 12 | print 'Removed [', stack.pop(), ']' 13 | 14 | def viewstack(): 15 | print str(stack) 16 | 17 | def showmenu(): 18 | prompt = """ 19 | p(U)sh 20 | p(O)p 21 | (V)iew 22 | (Q)uit 23 | 24 | Enter choice: """ 25 | 26 | done = 0 27 | while not done: 28 | 29 | chosen = 0 30 | while not chosen: 31 | try: 32 | choice = raw_input(prompt)[0] 33 | except (IndexError, EOFError, KeyboardInterrupt): 34 | choice = 'q' 35 | print '\nYou picked: [%s]' % choice 36 | if choice not in 'uovq': 37 | print 'invalid option, try again' 38 | else: 39 | chosen = 1 40 | 41 | if choice == 'q': done = 1 42 | if choice == 'u': pushit() 43 | if choice == 'o': popit() 44 | if choice == 'v': viewstack() 45 | 46 | if __name__ == '__main__': 47 | showmenu() 48 | -------------------------------------------------------------------------------- /ch11/alt/scope.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id$ 3 | # 4 | # scope.py -- variable scope example 5 | # 6 | 7 | """This script highlights some elements of variable scope 8 | and how it relates to Python programming. Global and local 9 | variables and the changing of their values are used to 10 | illustrate which variables are active in various execution 11 | scopes. 12 | 13 | main() contains global variables and calls proc1() and proc2(). 14 | """ 15 | 16 | j, k = 1, 2 # global 17 | 18 | 19 | def proc1(): # proc1() 20 | "proc1() includes local variables" 21 | 22 | j, k = 3, 4 # local 23 | 24 | print "j == %d and k == %d" % (j, k) 25 | 26 | k = 5 27 | 28 | 29 | def proc2(): # proc2() 30 | 'proc2() includes a local variable and calls proc1()' 31 | 32 | #global j # use global not local 'j' 33 | j = 6 # local 34 | 35 | proc1() 36 | 37 | print "j == %d and k == %d" % (j, k) 38 | 39 | 40 | k = 7 41 | 42 | proc1() 43 | 44 | print "j == %d and k == %d" % (j, k) 45 | 46 | j = 8 47 | 48 | proc2() 49 | 50 | print "j == %d and k == %d" % (j, k) 51 | -------------------------------------------------------------------------------- /ch18/mtfacfib.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from myThread import MyThread 4 | from time import ctime, sleep 5 | 6 | def fib(x): 7 | sleep(0.005) 8 | if x < 2: return 1 9 | return (fib(x-2) + fib(x-1)) 10 | 11 | def fac(x): 12 | sleep(0.1) 13 | if x < 2: return 1 14 | return (x * fac(x-1)) 15 | 16 | def sum(x): 17 | sleep(0.1) 18 | if x < 2: return 1 19 | return (x + sum(x-1)) 20 | 21 | funcs = (fib, fac, sum) 22 | n = 12 23 | 24 | def main(): 25 | nfuncs = range(len(funcs)) 26 | 27 | print '*** SINGLE THREAD' 28 | for i in nfuncs: 29 | print 'starting', funcs[i].__name__, \ 30 | 'at:', ctime() 31 | print funcs[i](n) 32 | print funcs[i].__name__, 'finished at:', \ 33 | ctime() 34 | 35 | print '\n*** MULTIPLE THREADS' 36 | threads = [] 37 | for i in nfuncs: 38 | t = MyThread(funcs[i], (n,), 39 | funcs[i].__name__) 40 | threads.append(t) 41 | 42 | for i in nfuncs: 43 | threads[i].start() 44 | 45 | for i in nfuncs: 46 | threads[i].join() 47 | print threads[i].getResult() 48 | 49 | print 'all DONE' 50 | 51 | if __name__ == '__main__': 52 | main() 53 | -------------------------------------------------------------------------------- /ch18/prodcons.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from random import randint 4 | from time import sleep 5 | from Queue import Queue 6 | from myThread import MyThread 7 | 8 | def writeQ(queue): 9 | print 'producing object for Q...', 10 | queue.put('xxx', 1) 11 | print "size now", queue.qsize() 12 | 13 | def readQ(queue): 14 | val = queue.get(1) 15 | print 'consumed object from Q... size now', \ 16 | queue.qsize() 17 | 18 | def writer(queue, loops): 19 | for i in range(loops): 20 | writeQ(queue) 21 | sleep(randint(1, 3)) 22 | 23 | def reader(queue, loops): 24 | for i in range(loops): 25 | readQ(queue) 26 | sleep(randint(2, 5)) 27 | 28 | funcs = [writer, reader] 29 | nfuncs = range(len(funcs)) 30 | 31 | def main(): 32 | nloops = randint(2, 5) 33 | q = Queue(32) 34 | 35 | threads = [] 36 | for i in nfuncs: 37 | t = MyThread(funcs[i], (q, nloops), \ 38 | funcs[i].__name__) 39 | threads.append(t) 40 | 41 | for i in nfuncs: 42 | threads[i].start() 43 | 44 | for i in nfuncs: 45 | threads[i].join() 46 | 47 | print 'all DONE' 48 | 49 | if __name__ == '__main__': 50 | main() 51 | -------------------------------------------------------------------------------- /ch11/easyMath.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from operator import add, sub 4 | from random import randint, choice 5 | 6 | ops = {'+': add, '-': sub} 7 | MAXTRIES = 2 8 | 9 | def doprob(): 10 | op = choice('+-') 11 | nums = [ randint(1,10) for i in range(2) ] 12 | nums.sort(reverse=True) 13 | ans = ops[op](*nums) 14 | pr = '%d %s %s = ' % (nums[0], op, nums[1]) 15 | oops = 0 16 | while True: 17 | try: 18 | if int(raw_input(pr)) == ans: 19 | print 'correct' 20 | break 21 | if oops == MAXTRIES: 22 | print 'sorry... the answer is\n%s%d' % (pr, ans) 23 | else: 24 | print 'incorrect... try again' 25 | oops += 1 26 | except (KeyboardInterrupt, 27 | EOFError, ValueError): 28 | print 'invalid input... try again' 29 | 30 | def main(): 31 | while True: 32 | doprob() 33 | try: 34 | opt = raw_input('Again? [y] ').lower() 35 | if opt and opt[0] == 'n': 36 | break 37 | except (KeyboardInterrupt, EOFError): 38 | break 39 | 40 | if __name__ == '__main__': 41 | main() 42 | -------------------------------------------------------------------------------- /ch18/alt/mtfacfib.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from myThread import MyThread 4 | from time import ctime, sleep 5 | 6 | def fib(x): 7 | sleep(0.005) 8 | if x < 2: return 1 9 | return (fib(x-2) + fib(x-1)) 10 | 11 | def fac(x): 12 | sleep(0.1) 13 | if x < 2: return 1 14 | return (x * fac(x-1)) 15 | 16 | def sum(x): 17 | sleep(0.1) 18 | if x < 2: return 1 19 | return (x + sum(x-1)) 20 | 21 | funcs = (fib, fac, sum) 22 | n = 12 23 | 24 | def main(): 25 | nfuncs = range(len(funcs)) 26 | 27 | print '*** SINGLE THREAD' 28 | for i in nfuncs: 29 | print 'starting', funcs[i].__name__, \ 30 | 'at:', ctime() 31 | print funcs[i](n) 32 | print funcs[i].__name__, 'finished at:', \ 33 | ctime() 34 | 35 | print '\n*** MULTIPLE THREADS' 36 | threads = [] 37 | for i in nfuncs: 38 | t = MyThread(funcs[i], (n,), 39 | funcs[i].__name__) 40 | threads.append(t) 41 | 42 | for i in nfuncs: 43 | threads[i].start() 44 | 45 | for i in nfuncs: 46 | threads[i].join() 47 | print threads[i].getResult() 48 | 49 | print 'all DONE at:', ctime() 50 | 51 | if __name__ == '__main__': 52 | main() 53 | -------------------------------------------------------------------------------- /ch13/twrapme.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from time import time, ctime 4 | 5 | class TimedWrapMe(object): 6 | 7 | def __init__(self, obj): 8 | self.__data = obj 9 | self.__ctime = self.__mtime = \ 10 | self.__atime = time() 11 | 12 | def set(self, obj): 13 | self.__data = obj 14 | self.__mtime = self.__atime = time() 15 | 16 | def get(self): 17 | self.__atime = time() 18 | return self.__data 19 | 20 | def gettimeval(self, t_type): 21 | if type(t_type) != type('') or \ 22 | t_type[0] not in 'cma': 23 | raise TypeError, \ 24 | "argument of 'c', 'm', or 'a' req'd" 25 | return eval('self._%s__%stime' % \ 26 | (self.__class__.__name__, t_type[0])) 27 | 28 | def gettimestr(self, t_type): 29 | return ctime(self.gettimeval(t_type)) 30 | 31 | def __repr__(self): 32 | self.__atime = time() 33 | return `self.__data` 34 | 35 | def __str__(self): 36 | self.__atime = time() 37 | return str(self.__data) 38 | 39 | def __getattr__(self, attr): # delegation 40 | self.__atime = time() 41 | return getattr(self.__data, attr) 42 | -------------------------------------------------------------------------------- /ch13/meta.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from warnings import warn 4 | 5 | class ReqStrSugRepr(object): 6 | 7 | def __init__(cls, name, bases, attrd): 8 | super(ReqStrSugRepr, cls).__init__( 9 | name, bases, attrd) 10 | 11 | if '__str__' not in attrd: 12 | raise TypeError( 13 | "Class requires overriding of __str__()") 14 | 15 | if '__repr__' not in attrd: 16 | warn( 17 | 'Class suggests overriding of __repr__()\n', 18 | stacklevel=3) 19 | 20 | print '*** Defined ReqStrSugRepr (meta)class\n' 21 | 22 | class Foo(object): 23 | __metaclass__ = ReqStrSugRepr 24 | 25 | def __str__(self): 26 | return 'Instance of class:', \ 27 | self.__class__.__name__ 28 | 29 | def __repr__(self): 30 | return self.__class__.__name__ 31 | 32 | print '*** Defined Foo class\n' 33 | 34 | class Bar(object): 35 | __metaclass__ = ReqStrSugRepr 36 | 37 | def __str__(self): 38 | return 'Instance of class:', \ 39 | self.__class__.__name__ 40 | 41 | print '*** Defined Bar class\n' 42 | 43 | class FooBar(object): 44 | __metaclass__ = ReqStrSugRepr 45 | 46 | print '*** Defined FooBar class\n' 47 | -------------------------------------------------------------------------------- /ch23/swhello.java: -------------------------------------------------------------------------------- 1 | import java.awt.*; 2 | import java.awt.event.*; 3 | import javax.swing.*; 4 | import java.lang.*; 5 | 6 | public class swhello extends JFrame { 7 | JPanel box; 8 | JLabel hello; 9 | JButton quit; 10 | 11 | public swhello() { 12 | super("JSwing"); 13 | JPanel box = new JPanel(new BorderLayout()); 14 | JLabel hello = new JLabel("Hello World!"); 15 | JButton quit = new JButton("QUIT"); 16 | 17 | ActionListener quitAction = new ActionListener() { 18 | public void actionPerformed(ActionEvent e) { 19 | System.exit(0); 20 | } 21 | }; 22 | quit.setBackground(Color.red); 23 | quit.setForeground(Color.white); 24 | quit.addActionListener(quitAction); 25 | box.add(hello, BorderLayout.NORTH); 26 | box.add(quit, BorderLayout.SOUTH); 27 | 28 | addWindowListener(new WindowAdapter() { 29 | public void windowClosing(WindowEvent e) { 30 | System.exit(0); 31 | } 32 | }); 33 | getContentPane().add(box); 34 | pack(); 35 | setVisible(true); 36 | } 37 | 38 | public static void main(String args[]) { 39 | swhello app = new swhello(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch23/alt/win32demo.pyw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from Tkinter import Tk 4 | from tkMessageBox import showwarning, askyesno 5 | 6 | def fromImport(mod, attr=None): 7 | # set attributes to import, if any 8 | if attr: 9 | if isinstance(attr, (list, tuple)): 10 | fromlist = attr 11 | else: 12 | fromlist = [attr] 13 | 14 | # perform actual import 15 | try: 16 | module = __import__(mod, globals(), locals(), fromlist) 17 | except ImportError: 18 | return None 19 | 20 | # return desired object 21 | if attr: 22 | return vars(module)[attr] 23 | else: 24 | return module 25 | 26 | if __name__=='__main__': 27 | Tk().withdraw() 28 | 29 | # app name; module and function name(s) 30 | dispatch = { 31 | 'Excel': 'excel', 32 | 'Word': 'word', 33 | 'Outlook': 'olook', 34 | 'PowerPoint': 'ppoint', 35 | } 36 | 37 | # run each main function for each app 38 | for eachApp in dispatch: 39 | if askyesno(eachApp, "Launch %s demo?" % eachApp): 40 | target = dispatch[eachApp] 41 | # "from target import target" 42 | targetFunc = fromImport(target, target) 43 | 44 | # exec if function imported successfully 45 | if targetFunc: 46 | targetFunc() 47 | else: 48 | showwarning('Could not start "%s"' % eachApp) 49 | -------------------------------------------------------------------------------- /ch17/getLatestFTP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import ftplib 4 | import os 5 | import socket 6 | 7 | HOST = 'ftp.mozilla.org' 8 | DIRN = 'pub/mozilla.org/webtools' 9 | FILE = 'bugzilla-LATEST.tar.gz' 10 | 11 | def main(): 12 | try: 13 | f = ftplib.FTP(HOST) 14 | except (socket.error, socket.gaierror), e: 15 | print 'ERROR: cannot reach "%s"' % HOST 16 | return 17 | print '*** Connected to host "%s"' % HOST 18 | 19 | try: 20 | f.login() 21 | except ftplib.error_perm: 22 | print 'ERROR: cannot login anonymously' 23 | f.quit() 24 | return 25 | print '*** Logged in as "anonymous"' 26 | 27 | try: 28 | f.cwd(DIRN) 29 | except ftplib.error_perm: 30 | print 'ERROR: cannot CD to "%s" folder' % DIRN 31 | f.quit() 32 | return 33 | print '*** Changed to "%s" folder' % DIRN 34 | 35 | try: 36 | f.retrbinary('RETR %s' % FILE, 37 | open(FILE, 'wb').write) 38 | except ftplib.error_perm: 39 | print 'ERROR: cannot read file "%s"' % FILE 40 | if os.path.exists(FILE): os.unlink(FILE) 41 | else: 42 | print '*** Downloaded "%s" to CWD' % FILE 43 | f.quit() 44 | return 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /ch19/pfaGUI2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.5 2 | 3 | from functools import partial as pto 4 | from Tkinter import Tk, Button, X 5 | from tkMessageBox import showinfo, showwarning, showerror 6 | 7 | WARN = 'warn' 8 | CRIT = 'crit' 9 | REGU = 'regu' 10 | 11 | SIGNS = { 12 | 'do not enter': CRIT, 13 | 'railroad crossing': WARN, 14 | '55\nspeed limit': REGU, 15 | 'wrong way': CRIT, 16 | 'merging traffic': WARN, 17 | 'one way': REGU, 18 | } 19 | 20 | critCB = lambda : showerror('Error', 'Error Button Pressed!') 21 | warnCB = lambda : showwarning('Warning', 22 | 'Warning Button Pressed!') 23 | infoCB = lambda : showinfo('Info', 'Info Button Pressed!') 24 | 25 | top = Tk() 26 | top.title('Road Signs') 27 | Button(top, text='QUIT', command=top.quit, 28 | bg='red', fg='white').pack() 29 | 30 | MyButton = pto(Button, top) 31 | CritButton = pto(MyButton, command=critCB, bg='white', fg='red') 32 | WarnButton = pto(MyButton, command=warnCB, bg='goldenrod1') 33 | ReguButton = pto(MyButton, command=infoCB, bg='white') 34 | 35 | for eachSign in SIGNS: 36 | signType = SIGNS[eachSign] 37 | cmd = '%sButton(text=%r%s).pack(fill=X, expand=True)' % ( 38 | signType.title(), eachSign, 39 | '.upper()' if signType == CRIT else '.title()') 40 | eval(cmd) 41 | 42 | top.mainloop() 43 | -------------------------------------------------------------------------------- /ch13/alt/descr-tef.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import pickle 5 | 6 | class FileDescr(object): 7 | saved = [] 8 | 9 | def __init__(self, name=None): 10 | self.name = name 11 | 12 | def __get__(self, obj, typ=None): 13 | if self.name not in FileDescr.saved: 14 | raise AttributeError, \ 15 | "%r used before assignment" % self.name 16 | 17 | try: 18 | f = open(self.name, 'r') 19 | val = pickle.load(f) 20 | f.close() 21 | return val 22 | except (pickle.UnpicklingError, IOError, 23 | EOFError, AttributeError, 24 | ImportError, IndexError), e: 25 | raise AttributeError, \ 26 | "could not read %r: %s" % self.name 27 | 28 | def __set__(self, obj, val): 29 | f = open(self.name, 'w') 30 | try: 31 | pickle.dump(val, f) 32 | FileDescr.saved.append(self.name) 33 | except (TypeError, pickle.PicklingError), e: 34 | raise AttributeError, \ 35 | "could not pickle %r" % self.name 36 | finally: 37 | f.close() 38 | 39 | def __delete__(self, obj): 40 | try: 41 | os.unlink(self.name) 42 | FileDescr.saved.remove(self.name) 43 | except (OSError, ValueError), e: 44 | pass 45 | -------------------------------------------------------------------------------- /ch06/alt/reversedSorted.py: -------------------------------------------------------------------------------- 1 | >>> reversed('abc') 2 | 3 | >>> sorted('abc') 4 | ['a', 'b', 'c'] 5 | >>> sorted('wesley foo bar') 6 | [' ', ' ', 'a', 'b', 'e', 'e', 'f', 'l', 'o', 'o', 'r', 's', 'w', 'y'] 7 | >>> for i in reversed('wesley foo bar'): 8 | print i, 9 | 10 | 11 | r a b o o f y e l s e w 12 | >>> for i in reversed(['wesley', 'foo', 'bar']): 13 | print i, 14 | 15 | 16 | bar foo wesley 17 | >>> sorted(['wesley', 'foo', 'bar']) 18 | ['bar', 'foo', 'wesley'] 19 | >>> 20 | 21 | >>> s = 'thequickbrownfoxjumpedoverthelazydog' 22 | >>> reversed(s) 23 | 24 | >>> for t in reversed(s): 25 | ... print t, 26 | ... 27 | g o d y z a l e h t r e v o d e p m u j x o f n w o r b k c i u q e h t 28 | >>> sorted(s) 29 | ['a', 'b', 'c', 'd', 'd', 'e', 'e', 'e', 'e', 'f', 'g', 'h', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'o', 'o', 'o', 'p', 'q', 'r', 'r', 't', 't', 'u', 'u', 'v', 'w', 'x', 'y', 'z'] 30 | >>> 31 | >>> s = 'foobar' 32 | >>> for t in reversed(s): 33 | ... print t, 34 | ... 35 | r a b o o f 36 | >>> sorted(s) 37 | ['a', 'b', 'f', 'o', 'o', 'r'] 38 | >>> s = ['They', 'stamp', 'them', 'when', "they're", 'small'] 39 | >>> for t in reversed(s): 40 | ... print t, 41 | ... 42 | small they're when them stamp They 43 | >>> sorted(s) 44 | ['They', 'small', 'stamp', 'them', "they're", 'when'] 45 | 46 | -------------------------------------------------------------------------------- /ch13/alt/descr-with.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import pickle 5 | 6 | class FileDescr(object): 7 | saved = [] 8 | 9 | def __init__(self, name=None): 10 | self.name = name 11 | 12 | def __get__(self, obj, typ=None): 13 | if self.name not in FileDescr.saved: 14 | raise AttributeError, \ 15 | "%r used before assignment" % self.name 16 | 17 | try: 18 | f = open(self.name, 'r') 19 | val = pickle.load(f) 20 | f.close() 21 | return val 22 | except (pickle.UnpicklingError, IOError, 23 | EOFError, AttributeError, 24 | ImportError, IndexError), e: 25 | raise AttributeError, \ 26 | "could not read %r: %s" % self.name 27 | 28 | def __set__(self, obj, val): 29 | with open(self.name, 'w') as f: 30 | try: 31 | pickle.dump(val, f) 32 | FileDescr.saved.append(self.name) 33 | except (TypeError, pickle.PicklingError), e: 34 | raise AttributeError, \ 35 | "could not pickle %r" % self.name 36 | 37 | def __delete__(self, obj): 38 | try: 39 | os.unlink(self.name) 40 | FileDescr.saved.remove(self.name) 41 | except (OSError, ValueError), e: 42 | pass 43 | -------------------------------------------------------------------------------- /ch13/descr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import pickle 5 | 6 | class FileDescr(object): 7 | saved = [] 8 | 9 | def __init__(self, name): 10 | self.name = name 11 | 12 | def __get__(self, obj, typ=None): 13 | if self.name not in FileDescr.saved: 14 | raise AttributeError, \ 15 | "%r used before assignment" % self.name 16 | 17 | try: 18 | f = open(self.name, 'r') 19 | val = pickle.load(f) 20 | f.close() 21 | return val 22 | except (pickle.UnpicklingError, IOError, 23 | EOFError, AttributeError, 24 | ImportError, IndexError), e: 25 | raise AttributeError, \ 26 | "could not read %r: %s" % self.name 27 | 28 | def __set__(self, obj, val): 29 | try: 30 | f = open(self.name, 'w') 31 | pickle.dump(val, f) 32 | FileDescr.saved.append(self.name) 33 | except (IOError, TypeError, pickle.PicklingError), e: 34 | raise AttributeError, \ 35 | "could not pickle %r" % self.name 36 | finally: 37 | f.close() 38 | 39 | def __delete__(self, obj): 40 | try: 41 | os.unlink(self.name) 42 | FileDescr.saved.remove(self.name) 43 | except (OSError, ValueError), e: 44 | pass 45 | -------------------------------------------------------------------------------- /ch13/descr0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import pickle 5 | 6 | class FileDescr(object): 7 | saved = [] 8 | 9 | def __init__(self, name=None): 10 | self.name = name 11 | 12 | def __get__(self, obj, typ=None): 13 | if self.name not in FileDescr.saved: 14 | raise AttributeError, \ 15 | "%r used before assignment" % self.name 16 | 17 | try: 18 | f = open(self.name, 'r') 19 | val = pickle.load(f) 20 | f.close() 21 | return val 22 | except (pickle.UnpicklingError, IOError, 23 | EOFError, AttributeError, 24 | ImportError, IndexError), e: 25 | raise AttributeError, \ 26 | "could not read %r: %s" % self.name 27 | 28 | def __set__(self, obj, val): 29 | f = open(self.name, 'w') 30 | try: 31 | try: 32 | pickle.dump(val, f) 33 | FileDescr.saved.append(self.name) 34 | except (TypeError, pickle.PicklingError), e: 35 | raise AttributeError, \ 36 | "could not pickle %r" % self.name 37 | finally: 38 | f.close() 39 | 40 | def __delete__(self, obj): 41 | try: 42 | os.unlink(self.name) 43 | FileDescr.saved.remove(self.name) 44 | except (OSError, ValueError), e: 45 | pass 46 | -------------------------------------------------------------------------------- /ch08/alt/maxFact.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id: maxFact.py,v 1.1 2000/03/16 02:33:40 wesc Exp $ 4 | 5 | maxFact.py -- calculates the largest factor of a number 6 | (or indicate that it is prime) 7 | ''' 8 | 9 | # 10 | # calcMaxFac(num) -- return -1 if prime, largest factor otherwise 11 | # 12 | def calcMaxFac(num): 13 | # composite smallest possible factor is 2 14 | count = num / 2 15 | 16 | # count backwards to 0 looking for first factor 17 | while count > 1: 18 | 19 | # break if factor found... 20 | if (num % count == 0): 21 | break 22 | 23 | # otherwise decrement and continue 24 | else: 25 | count = count - 1 26 | 27 | # reached 1 without finding a factor, ergo prime; 28 | # (example of while-else statement) 29 | else: 30 | return -1 31 | 32 | # return largest factor found 33 | return count 34 | 35 | 36 | # 37 | # showMaxFac(x, y) -- return largest factors of numbers from x to y, 38 | # or an indication a number if prime if applicable 39 | # 40 | def showMaxFacs(x, y): 41 | for eachNum in range(x, y): 42 | res = calcMaxFac(eachNum) 43 | if res == -1: 44 | print eachNum, 'is prime' 45 | else: 46 | print eachNum, 'has a largest factor of', res 47 | 48 | 49 | # show the largest factors of values 10 - 20 as a test 50 | if __name__ == '__main__': 51 | showMaxFacs(10, 21) 52 | -------------------------------------------------------------------------------- /ch13/descrPRE25.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import pickle 5 | 6 | class FileDescr(object): 7 | saved = [] 8 | 9 | def __init__(self, name): 10 | self.name = name 11 | 12 | def __get__(self, obj, typ=None): 13 | if self.name not in FileDescr.saved: 14 | raise AttributeError, \ 15 | "%r used before assignment" % self.name 16 | 17 | try: 18 | f = open(self.name, 'r') 19 | val = pickle.load(f) 20 | f.close() 21 | return val 22 | except (pickle.UnpicklingError, IOError, 23 | EOFError, AttributeError, 24 | ImportError, IndexError), e: 25 | raise AttributeError, \ 26 | "could not read %r: %s" % self.name 27 | 28 | def __set__(self, obj, val): 29 | try: 30 | try: 31 | f = open(self.name, 'w') 32 | pickle.dump(val, f) 33 | FileDescr.saved.append(self.name) 34 | except (IOError, TypeError, pickle.PicklingError), e: 35 | raise AttributeError, \ 36 | "could not pickle %r" % self.name 37 | finally: 38 | f.close() 39 | 40 | def __delete__(self, obj): 41 | try: 42 | os.unlink(self.name) 43 | FileDescr.saved.remove(self.name) 44 | except (OSError, ValueError), e: 45 | pass 46 | -------------------------------------------------------------------------------- /ch19/animalWx.pyw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import wx 4 | 5 | class MyFrame(wx.Frame): 6 | def __init__(self, parent=None, id=-1, title=''): 7 | wx.Frame.__init__(self, parent, id, title, 8 | size=(200,140)) 9 | top = wx.Panel(self) 10 | sizer = wx.BoxSizer(wx.VERTICAL) 11 | font = wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD) 12 | lb = wx.StaticText(top, -1, 13 | 'Animals (in pairs; min: pair, max: dozen)') 14 | sizer.Add(lb) 15 | 16 | c1 = wx.StaticText(top, -1, 'Number:') 17 | c1.SetFont(font) 18 | ct = wx.SpinCtrl(top, -1, '2', min=2, max=12) 19 | sizer.Add(c1) 20 | sizer.Add(ct) 21 | 22 | c2 = wx.StaticText(top, -1, 'Type:') 23 | c2.SetFont(font) 24 | cb = wx.ComboBox(top, -1, '', 25 | choices=('dog', 'cat', 'hamster', 'python')) 26 | sizer.Add(c2) 27 | sizer.Add(cb) 28 | 29 | qb = wx.Button(top, -1, "QUIT") 30 | qb.SetBackgroundColour('red') 31 | qb.SetForegroundColour('white') 32 | self.Bind(wx.EVT_BUTTON, 33 | lambda e: self.Close(True), qb) 34 | sizer.Add(qb) 35 | 36 | top.SetSizer(sizer) 37 | self.Layout() 38 | 39 | class MyApp(wx.App): 40 | def OnInit(self): 41 | frame = MyFrame(title="wxWidgets") 42 | frame.Show(True) 43 | self.SetTopWindow(frame) 44 | return True 45 | 46 | def main(): 47 | app = MyApp() 48 | app.MainLoop() 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /ch13/numstr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | class NumStr(object): 4 | 5 | def __init__(self, num=0, string=''): 6 | self.__num = num 7 | self.__string = string 8 | 9 | def __str__(self): # define for str() 10 | return '[%d :: %r]' % \ 11 | (self.__num, self.__string) 12 | __repr__ = __str__ 13 | 14 | def __add__(self, other): # define for s+o 15 | if isinstance(other, NumStr): 16 | return self.__class__(self.__num + \ 17 | other.__num, 18 | self.__string + other.__string) 19 | else: 20 | raise TypeError, \ 21 | 'Illegal argument type for built-in operation' 22 | 23 | def __mul__(self, num): # define for s*o 24 | if isinstance(num, int): 25 | return self.__class__(self.__num * num, 26 | self.__string * num) 27 | else: 28 | raise TypeError, \ 29 | 'Illegal argument type for built-in operation' 30 | 31 | def __nonzero__(self): # reveal tautology 32 | return self.__num or len(self.__string) 33 | 34 | def __norm_cval(self, cmpres): # normalize cmp() 35 | return cmp(cmpres, 0) 36 | 37 | def __cmp__(self, other): # define for cmp() 38 | return self.__norm_cval( 39 | cmp(self.__num, other.__num)) + \ 40 | self.__norm_cval( 41 | cmp(self.__string, other.__string)) 42 | -------------------------------------------------------------------------------- /ch07/userpw.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | db = {} 4 | 5 | def newuser(): 6 | prompt = 'login desired: ' 7 | while True: 8 | name = raw_input(prompt) 9 | if db.has_key(name): 10 | prompt = 'name taken, try another: ' 11 | continue 12 | else: 13 | break 14 | pwd = raw_input('passwd: ') 15 | db[name] = pwd 16 | 17 | def olduser(): 18 | name = raw_input('login: ') 19 | pwd = raw_input('passwd: ') 20 | passwd = db.get(name) 21 | if passwd == pwd: 22 | pass 23 | else: 24 | print 'login incorrect' 25 | return 26 | 27 | print 'welcome back', name 28 | 29 | def showmenu(): 30 | prompt = """ 31 | (N)ew User Login 32 | (E)xisting User Login 33 | (Q)uit 34 | 35 | Enter choice: """ 36 | 37 | done = False 38 | while not done: 39 | chosen = False 40 | while not chosen: 41 | try: 42 | choice = raw_input(prompt).strip()[0].lower() 43 | except (EOFError, KeyboardInterrupt): 44 | choice = 'q' 45 | print '\nYou picked: [%s]' % choice 46 | 47 | if choice not in 'neq': 48 | print 'invalid menu option, try again' 49 | else: 50 | chosen = True 51 | 52 | if choice == 'q': done = True 53 | if choice == 'n': newuser() 54 | if choice == 'e': olduser() 55 | 56 | if __name__ == '__main__': 57 | showmenu() 58 | -------------------------------------------------------------------------------- /ch20/alt/myhttpd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from os import curdir, sep, getcwd 4 | from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 5 | 6 | # subclass BaseHTTPRequestHandler and support GET requests 7 | class MyHandler(BaseHTTPRequestHandler): 8 | 9 | # handle GET request 10 | def do_GET(self): 11 | # check if we can read file and return it 12 | try: 13 | f = open(curdir + sep + self.path) 14 | self.send_response(200) 15 | self.send_header('Content-type', 'text/html') 16 | self.end_headers() 17 | self.wfile.write(f.read()) 18 | f.close() 19 | 20 | # if not, assume non-existent file 21 | except IOError: 22 | self.send_error(404, 'File Not Found: %s' % self.path) 23 | 24 | 25 | def main(): 26 | 27 | # attempt to start server 28 | try: 29 | # change directory if necessary by adding call to os.chdir() 30 | #os.chdir('/usr/local/httpd/htdocs') 31 | 32 | # create server 33 | server = HTTPServer(('', 80), MyHandler) 34 | print 'Welcome to the machine... hit ^C once or twice to quit' 35 | print 'cwd:', getcwd() 36 | 37 | # enter server loop 38 | server.serve_forever() 39 | 40 | # quit requested 41 | except KeyboardInterrupt: 42 | print '^C received, shutting down server' 43 | server.socket.close() 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /ch06/alt/idcheck.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id$ 4 | 5 | idcheck.py -- checks identifiers for validity 6 | 7 | This application is limited in that it currently only supports 8 | checking identifiers with length > 1 (does not process identifiers 9 | of length greater than 1. This application also does not recognize 10 | do keywords. 11 | 12 | Exercise: 13 | 14 | 6-2) update this script to process identifiers of length 1 15 | as well as recognizing keywords as invalid identifiers 16 | (for use by the programmer; they are valid Python 17 | identifiers otherwise). 18 | ''' 19 | 20 | import string # string utility module 21 | 22 | # create alphabet and number sets 23 | alphas = string.letters + '_' 24 | nums = string.digits 25 | 26 | # salutation message and input prompt 27 | print 'Welcome to the Identifier Checker v1.0' 28 | print 'Testees must be at least 2 chars long.' 29 | inp = raw_input('Identifier to test? ') 30 | 31 | # only take action for identifiers with length > 1 32 | if len(inp) > 1: 33 | 34 | # first character must be alphabetic 35 | if inp[0] not in alphas: 36 | print 'invalid: first symbol must be alphabetic' 37 | 38 | # remaning characters can be alphanumeric 39 | else: 40 | for otherChar in inp[1:]: 41 | if otherChar not in alphas + nums: 42 | print 'invalid: remaining symbols must be alphanumeric' 43 | break 44 | else: 45 | print "okay as an identifier" 46 | else: 47 | print 'invalid: length must be > 1' 48 | -------------------------------------------------------------------------------- /ch23/estock.pyw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from Tkinter import Tk 4 | from time import sleep, ctime 5 | from tkMessageBox import showwarning 6 | from urllib import urlopen 7 | import win32com.client as win32 8 | 9 | warn = lambda app: showwarning(app, 'Exit?') 10 | RANGE = range(3, 8) 11 | TICKS = ('YHOO', 'GOOG', 'EBAY', 'AMZN') 12 | COLS = ('TICKER', 'PRICE', 'CHG', '%AGE') 13 | URL = 'http://quote.yahoo.com/d/quotes.csv?s=%s&f=sl1c1p2' 14 | 15 | def excel(): 16 | app = 'Excel' 17 | xl = win32.gencache.EnsureDispatch('%s.Application' % app) 18 | ss = xl.Workbooks.Add() 19 | sh = ss.ActiveSheet 20 | xl.Visible = True 21 | sleep(1) 22 | 23 | sh.Cells(1, 1).Value = 'Python-to-%s Stock Quote Demo' % app 24 | sleep(1) 25 | sh.Cells(3, 1).Value = 'Prices quoted as of: %s' % ctime() 26 | sleep(1) 27 | for i in range(4): 28 | sh.Cells(5, i+1).Value = COLS[i] 29 | sleep(1) 30 | sh.Range(sh.Cells(5, 1), sh.Cells(5, 4)).Font.Bold = True 31 | sleep(1) 32 | row = 6 33 | 34 | u = urlopen(URL % ','.join(TICKS)) 35 | for data in u: 36 | tick, price, chg, per = data.split(',') 37 | sh.Cells(row, 1).Value = eval(tick) 38 | sh.Cells(row, 2).Value = '%.2f' % round(float(price), 2) 39 | sh.Cells(row, 3).Value = chg 40 | sh.Cells(row, 4).Value = eval(per.rstrip()) 41 | row += 1 42 | sleep(1) 43 | u.close() 44 | 45 | warn(app) 46 | ss.Close(False) 47 | xl.Application.Quit() 48 | 49 | if __name__=='__main__': 50 | Tk().withdraw() 51 | excel() 52 | -------------------------------------------------------------------------------- /ch19/animalGtk.pyw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import pygtk 4 | pygtk.require('2.0') 5 | import gtk 6 | import pango 7 | 8 | class GTKapp(object): 9 | def __init__(self): 10 | top = gtk.Window(gtk.WINDOW_TOPLEVEL) 11 | top.connect("delete_event", gtk.main_quit) 12 | top.connect("destroy", gtk.main_quit) 13 | box = gtk.VBox(False, 0) 14 | lb = gtk.Label( 15 | 'Animals (in pairs; min: pair, max: dozen)') 16 | box.pack_start(lb) 17 | 18 | sb = gtk.HBox(False, 0) 19 | adj = gtk.Adjustment(2, 2, 12, 2, 4, 0) 20 | sl = gtk.Label('Number:') 21 | sl.modify_font( 22 | pango.FontDescription("Arial Bold 10")) 23 | sb.pack_start(sl) 24 | ct = gtk.SpinButton(adj, 0, 0) 25 | sb.pack_start(ct) 26 | box.pack_start(sb) 27 | 28 | cb = gtk.HBox(False, 0) 29 | c2 = gtk.Label('Type:') 30 | cb.pack_start(c2) 31 | ce = gtk.combo_box_entry_new_text() 32 | for animal in ('dog', 'cat', 'hamster', 'python'): 33 | ce.append_text(animal) 34 | cb.pack_start(ce) 35 | box.pack_start(cb) 36 | 37 | qb = gtk.Button("") 38 | red = gtk.gdk.color_parse('red') 39 | sty = qb.get_style() 40 | for st in (gtk.STATE_NORMAL, 41 | gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE): 42 | sty.bg[st] = red 43 | qb.set_style(sty) 44 | ql = qb.child 45 | ql.set_markup('QUIT') 46 | qb.connect_object("clicked", 47 | gtk.Widget.destroy, top) 48 | box.pack_start(qb) 49 | top.add(box) 50 | top.show_all() 51 | 52 | if __name__ == '__main__': 53 | animal = GTKapp() 54 | gtk.main() 55 | -------------------------------------------------------------------------------- /ch20/friends2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import cgi 4 | 5 | header = 'Content-Type: text/html\n\n' 6 | 7 | formhtml = ''' 8 | Friends CGI Demo 9 |

Friends list for: NEW USER

10 |
11 | Enter your Name: 12 | 13 | 14 |

How many friends do you have? 15 | %s 16 |

''' 17 | 18 | fradio = ' %s\n' 19 | 20 | def showForm(): 21 | friends = '' 22 | for i in [0, 10, 25, 50, 100]: 23 | checked = '' 24 | if i == 0: 25 | checked = 'CHECKED' 26 | friends = friends + fradio % \ 27 | (str(i), checked, str(i)) 28 | 29 | print header + formhtml % (friends) 30 | 31 | reshtml = ''' 32 | Friends CGI Demo 33 |

Friends list for: %s

34 | Your name is: %s

35 | You have %s friends. 36 | ''' 37 | 38 | def doResults(who, howmany): 39 | print header + reshtml % (who, who, howmany) 40 | 41 | def process(): 42 | form = cgi.FieldStorage() 43 | if form.has_key('person'): 44 | who = form['person'].value 45 | else: 46 | who = 'NEW USER' 47 | 48 | if form.has_key('howmany'): 49 | howmany = form['howmany'].value 50 | else: 51 | howmany = 0 52 | 53 | if form.has_key('action'): 54 | doResults(who, howmany) 55 | else: 56 | showForm() 57 | 58 | if __name__ == '__main__': 59 | process() 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Core-Python-Programming-2nd-Edition-Examples-and-Source-Code 2 | ============================================================ 3 | 4 | Examples and source code from the book "Core Python Programming", 2nd Edition, by Wesley J. Chun 5 | 6 | These directories contain all of the source code for the 7 | applications in the book, e.g., Example x.y, with each 8 | directory representing the code for a chapter in the book 9 | which features at least one code Example. 10 | 11 | In each directory, you may also find a subdirectory named 12 | "alt" which will contain alternative source code. These 13 | can include: 14 | 15 | - Applications that have been more fully-commented 16 | - Some of the more lengthy code snippets featured as 17 | chapter reading 18 | - Modified applications which run on older (or newer) 19 | versions of Python 20 | 21 | ---- 22 | 23 | **License** 24 | 25 | Source code for the book is released under the 26 | Creative Commons Attribution-SharedAlike2.5 License. 27 | This means that you are free to: 28 | 29 | * copy, distribute, display, and perform the work 30 | * make derivative works 31 | * make commercial use of the work 32 | 33 | ...under the following conditions: 34 | 35 | * Attribution: You must attribute the work in this 36 | manner specified by the author or licensor... state 37 | the following in copies or derivations of the work: 38 | 39 | "(c) 2007 CyberWeb Consulting and Pearson Education. 40 | All Rights Reserved." 41 | 42 | * Share Alike. If you alter, transform, or build 43 | upon this work, you may distribute the resulting 44 | work only under a license identical to this one. 45 | 46 | For more information, see: 47 | http://creativecommons.org/licenses/by-sa/2.5/ -------------------------------------------------------------------------------- /ch15/alt/gendata.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id$ 3 | # 4 | # gendata.py -- generates test data 5 | # 6 | # created on 00/05/19 by wesc 7 | # 8 | 9 | from random import randint, choice 10 | from time import ctime 11 | from sys import maxint # (value, not function) 12 | from string import lowercase 13 | from os.path import exists 14 | 15 | doms = ( 'com', 'edu', 'net', 'org', 'gov' ) 16 | 17 | def main(): 18 | 19 | # this long version saves output to files which 20 | # can be directly used with regular expressions 21 | # (it does not write the strings to the screen) 22 | 23 | # open new test file 24 | i = 0 25 | fn = '/tmp/data%d.txt' % i 26 | while exists(fn): 27 | i = i + 1 28 | fn = '/tmp/data%d.txt' % i 29 | f = open(fn, 'w') 30 | 31 | # write test data and close file 32 | for i in range(randint(5, 10)): 33 | 34 | # randomly choose a date integer and 35 | # calculate the corresponding date string 36 | dtint = randint(0, maxint-1) 37 | dtstr = ctime(dtint) 38 | 39 | # the login should be between 4 and 7 chars in length; 40 | # the domain should be 41 | loginlen = randint(4, 7) 42 | login = '' 43 | for j in range(loginlen): 44 | login = login + choice(lowercase) 45 | 46 | domainlen = randint(loginlen, 12) 47 | dom = '' 48 | for j in range(domainlen): 49 | dom = dom + choice(lowercase) 50 | f.write('%s:%s@%s.%s:%d-%d-%d\n' % (dtstr, login, 51 | dom, choice(doms), dtint, loginlen, domainlen)) 52 | 53 | # close test file 54 | f.close() 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /ch14/loopmake.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | dashes = '\n' + '-' * 50 4 | exec_dict = { 5 | 6 | 'f': """ # for loop 7 | for %s in %s: 8 | print %s 9 | """, 10 | 11 | 's': """ # sequence while loop 12 | %s = 0 13 | %s = %s 14 | while %s < len(%s): 15 | print %s[%s] 16 | %s = %s + 1 17 | """, 18 | 19 | 'n': """ # counting while loop 20 | %s = %d 21 | while %s < %d: 22 | print %s 23 | %s = %s + %d 24 | """ 25 | } 26 | 27 | def main(): 28 | 29 | ltype = raw_input('Loop type? (For/While) ') 30 | dtype = raw_input('Data type? (Number/Sequence) ') 31 | 32 | if dtype == 'n': 33 | start = input('Starting value? ') 34 | stop = input('Ending value (non-inclusive)? ') 35 | step = input('Stepping value? ') 36 | seq = str(range(start, stop, step)) 37 | 38 | else: 39 | seq = raw_input('Enter sequence: ') 40 | 41 | var = raw_input('Iterative variable name? ') 42 | 43 | if ltype == 'f': 44 | exec_str = exec_dict['f'] % (var, seq, var) 45 | 46 | elif ltype == 'w': 47 | if dtype == 's': 48 | svar = raw_input('Enter sequence name? ') 49 | exec_str = exec_dict['s'] % \ 50 | (var, svar, seq, var, svar, svar, var, var, var) 51 | 52 | elif dtype == 'n': 53 | exec_str = exec_dict['n'] % \ 54 | (var, start, var, stop, var, var, var, step) 55 | 56 | print dashes 57 | print 'The custom-generated code for you is:' + dashes 58 | print exec_str + dashes 59 | print 'Test execution of the code:' + dashes 60 | exec exec_str 61 | print dashes 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /ch13/alt/twrapme.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id: twrapme.py,v 1.1 2000/06/02 08:14:55 wesc Exp $ 3 | # 4 | # twrapme.py -- another simple wrapping example 5 | # 6 | # created on 00/04/26 by wesc 7 | # 8 | 9 | from time import time, ctime # import time.time(), time.ctime() 10 | 11 | class TimedWrapMe: 12 | 13 | # constructor, sets data item to wrap and 14 | # updates create, modify, and access times 15 | def __init__(self, obj): 16 | self.__data = obj 17 | self.__ctime = self.__mtime = self.__atime = time() 18 | 19 | # sets new data value, updates modify and access times 20 | def set(self, obj): 21 | self.__data = obj 22 | self.__mtime = self.__atime = time() 23 | 24 | # gets current data value, updates access time 25 | def get(self): 26 | self.__atime = time() 27 | return self.__data 28 | 29 | # get request time value 30 | def gettimeval(self, t_type): 31 | if type(t_type) != type('') or t_type[0] not in 'cma': 32 | raise TypeError, "gettime() requires argument of 'c', 'm', or 'a'" 33 | return eval('self._%s__%stime' % (self.__class__.__name__, t_type[0])) 34 | 35 | # get request time string 36 | def gettimestr(self, t_type): 37 | return ctime(self.gettimeval(t_type)) 38 | 39 | # repr() and `` call this 40 | def __repr__(self): 41 | self.__atime = time() 42 | return `self.__data` 43 | 44 | # str() calls this 45 | def __str__(self): 46 | self.__atime = time() 47 | return str(self.__data) 48 | 49 | # delegate all other functionality to object's native methods 50 | def __getattr__(self, attr): 51 | self.__atime = time() 52 | return getattr(self.__data, attr) 53 | -------------------------------------------------------------------------------- /ch09/ospathex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | for tmpdir in ('/tmp', 'c:/windows/temp'): 5 | if os.path.isdir(tmpdir): 6 | break 7 | else: 8 | print 'no temp directory available' 9 | tmpdir = '' 10 | 11 | if tmpdir: 12 | os.chdir(tmpdir) 13 | cwd = os.getcwd() 14 | print '*** current temporary directory' 15 | print cwd 16 | 17 | print '*** creating example directory...' 18 | os.mkdir('example') 19 | os.chdir('example') 20 | cwd = os.getcwd() 21 | print '*** new working directory:' 22 | print cwd 23 | print '*** original directory listing:' 24 | print os.listdir(cwd) 25 | 26 | print '*** creating test file...' 27 | file = open('test', 'w') 28 | file.write('foo\n') 29 | file.write('bar\n') 30 | file.close() 31 | print '*** updated directory listing:' 32 | print os.listdir(cwd) 33 | 34 | print "*** renaming 'test' to 'filetest.txt'" 35 | os.rename('test', 'filetest.txt') 36 | print '*** updated directory listing:' 37 | print os.listdir(cwd) 38 | 39 | path = os.path.join(cwd, os.listdir(cwd)[0]) 40 | print '*** full file pathname:' 41 | print path 42 | print '*** (pathname, basename) == ' 43 | print os.path.split(path) 44 | print '*** (filename, extension) == ' 45 | print os.path.splitext(os.path.basename(path)) 46 | 47 | print '*** displaying file contents:' 48 | file = open(path) 49 | allLines = file.readlines() 50 | file.close() 51 | for eachLine in allLines: 52 | print eachLine, 53 | 54 | print '*** deleting test file' 55 | os.remove(path) 56 | print '*** updated directory listing:' 57 | print os.listdir(cwd) 58 | os.chdir(os.pardir) 59 | print '*** deleting test directory' 60 | os.rmdir('example') 61 | print '*** DONE' 62 | -------------------------------------------------------------------------------- /ch13/alt/descr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import pickle 5 | 6 | class FileDescr(object): 7 | ''' 8 | FileDescr -- description which uses the file 9 | system to archive instance attributes 10 | ''' 11 | saved = [] 12 | 13 | def __init__(self, name): 14 | '__init__() -- saves the attribute name' 15 | self.name = name 16 | 17 | def __get__(self, obj, typ=None): 18 | '__get__() -- retrives attribute from disk' 19 | self.name = name 20 | if self.name not in FileDescr.saved: 21 | raise AttributeError, \ 22 | "%r used before assignment" % self.name 23 | 24 | # open pickle file and load object; choke on failure 25 | try: 26 | f = open(self.name, 'r') 27 | val = pickle.load(f) 28 | f.close() 29 | return val 30 | except (pickle.UnpicklingError, IOError, 31 | EOFError, AttributeError, 32 | ImportError, IndexError), e: 33 | raise AttributeError, \ 34 | "could not read %r: %s" % self.name 35 | 36 | def __set__(self, obj, val): 37 | '__set__() -- saves attribute to disk' 38 | try: 39 | try: 40 | f = open(self.name, 'w') 41 | pickle.dump(val, f) 42 | FileDescr.saved.append(self.name) 43 | except (IOError, TypeError, pickle.PicklingError), e: 44 | raise AttributeError, \ 45 | "could not pickle %r" % self.name 46 | finally: 47 | f.close() 48 | 49 | def __delete__(self, obj): 50 | '__set__() -- removes instance attribute' 51 | try: 52 | os.unlink(self.name) 53 | FileDescr.saved.remove(self.name) 54 | except (OSError, ValueError), e: 55 | pass 56 | -------------------------------------------------------------------------------- /ch11/alt/deco.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from time import ctime, sleep 4 | 5 | ''' 6 | def counter(func): 7 | if not hasattr(func, 'ncalls'): 8 | print '*** initializing ctr' 9 | func.ncalls = [0] 10 | def wrappedFunc(): 11 | func.ncalls[0] += 1 12 | print '*** incrementing ctr to', func.ncalls 13 | print 'INSIDE: id(func) =', id(func) 14 | return func() 15 | print 'id(func) =', id(func) 16 | print 'id(wrappedfunc) =', id(wrappedFunc) 17 | wrappedFunc.ncalls = func.ncalls 18 | return wrappedFunc 19 | ''' 20 | 21 | def tsfunc(func): 22 | def wrappedFunc(): 23 | print '[%s] %s() called' % ( 24 | ctime(), func.__name__) 25 | return func() 26 | return wrappedFunc 27 | 28 | @tsfunc 29 | def foo(): 30 | pass 31 | 32 | foo() 33 | sleep(4) 34 | 35 | for i in range(2): 36 | sleep(1) 37 | foo() 38 | 39 | ''' 40 | #exer 41 | update example XXX to: 42 | - write the timestamp to a logfile instead of screen output 43 | - time how long it takes to exec the given function, i.e., see the timeit() exercise above 44 | - create a function registry: 45 | track the number of functions which have registered with your system, 46 | how many times those functions have been called, 47 | and what are the avg time of each execution and total time of execution 48 | 49 | - write a memoizer... for small recursive functions or just for simple functions that are called a lot, cache the results given a set of arguments (must be hashable, i.e, immutable objects), so that if the same function is called again with the same args, then just return the previously saved value instead of (re)running the function from scratch. There are many examples online (use a search engine), so that even if you are inspired by an existing piece of code, customize that code by making an improvement that is truly your own. 50 | 51 | ''' 52 | -------------------------------------------------------------------------------- /ch13/alt/moneyfmt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id: moneyfmt.py,v 1.2 2000/02/07 07:46:09 wesc Exp $ 3 | # 4 | # moneyfmt.py -- create a class that prints a floating-point 5 | # value in a financial format 6 | # 7 | # created 00/02/07 by wesc 8 | # 9 | 10 | """Implements the Dollar class for displaying a financial 11 | format for single floating-point values. Also see 12 | moneyfmt.MoneyFmt.__doc__. 13 | """ 14 | 15 | class MoneyFmt(object): 16 | 17 | """This class... 18 | 19 | x = dollar.Dollar(amount) # amount is a float 20 | 21 | NOTE: str() will give the formatted display while repr() and `` will 22 | give the raw float value. This allows for both pretty-printing 23 | output as well as the ability to still manipulate the values. 24 | 25 | Methods: 26 | 27 | x.update([amount]) -- updates the value of the number 28 | """ 29 | 30 | def __init__(self, value=0.): # constructor 31 | 32 | self.value = float(value) 33 | 34 | 35 | def update(self, value=None): # allow updates 36 | 37 | """x.update([amount]) 38 | You can update the amount with this method. 39 | If the value is missing, the value is not updated. 40 | Also see moneyfmt.MoneyFmt.__doc__. 41 | """ 42 | 43 | ### 44 | ### (a) FILL THIS IN 45 | ### 46 | 47 | 48 | def __nonzero__(self): # boolean test (same as float) 49 | 50 | return int(self.value) 51 | 52 | 53 | def __repr__(self): # standalone, as a float number 54 | 55 | return str(self.value) 56 | 57 | 58 | def __str__(self): # display in requested format 59 | 60 | val = '' 61 | 62 | ### 63 | ### (b) FILL THIS IN... don't forget about negative numbers too!! 64 | ### 65 | 66 | return val 67 | -------------------------------------------------------------------------------- /ch22/Extest2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int fac(int n) 6 | { 7 | if (n < 2) return(1); 8 | return (n)*fac(n-1); 9 | } 10 | 11 | char *reverse(char *s) 12 | { 13 | register char t, 14 | *p = s, 15 | *q = (s + (strlen(s) - 1)); 16 | 17 | while (s && (p < q)) 18 | { 19 | t = *p; 20 | *p++ = *q; 21 | *q-- = t; 22 | } 23 | return(s); 24 | } 25 | 26 | int test() 27 | { 28 | char s[BUFSIZ]; 29 | printf("4! == %d\n", fac(4)); 30 | printf("8! == %d\n", fac(8)); 31 | printf("12! == %d\n", fac(12)); 32 | strcpy(s, "abcdef"); 33 | printf("reversing 'abcdef', we get '%s'\n", \ 34 | reverse(s)); 35 | strcpy(s, "madam"); 36 | printf("reversing 'madam', we get '%s'\n", \ 37 | reverse(s)); 38 | return 0; 39 | } 40 | 41 | #include "Python.h" 42 | 43 | static PyObject * 44 | Extest_fac(PyObject *self, PyObject *args) 45 | { 46 | int num; 47 | if (!PyArg_ParseTuple(args, "i", &num)) 48 | return NULL; 49 | return (PyObject*)Py_BuildValue("i", fac(num)); 50 | } 51 | 52 | static PyObject * 53 | Extest_doppel(PyObject *self, PyObject *args) 54 | { 55 | char *orig_str; 56 | char *dupe_str; 57 | PyObject* retval; 58 | 59 | if (!PyArg_ParseTuple(args, "s", &orig_str)) 60 | return NULL; 61 | retval = (PyObject*)Py_BuildValue("ss", orig_str, 62 | dupe_str=reverse(strdup(orig_str))); 63 | free(dupe_str); 64 | return retval; 65 | } 66 | 67 | static PyObject * 68 | Extest_test(PyObject *self, PyObject *args) 69 | { 70 | test(); 71 | return (PyObject*)Py_BuildValue(""); 72 | } 73 | 74 | static PyMethodDef 75 | ExtestMethods[] = 76 | { 77 | { "fac", Extest_fac, METH_VARARGS }, 78 | { "doppel", Extest_doppel, METH_VARARGS }, 79 | { "test", Extest_test, METH_VARARGS }, 80 | { NULL, NULL }, 81 | }; 82 | 83 | void initExtest() 84 | { 85 | Py_InitModule("Extest", ExtestMethods); 86 | } 87 | -------------------------------------------------------------------------------- /ch20/alt/friends2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id: friends2.py,v 1.1 2000/12/31 01:32:45 wesc Exp $ 4 | 5 | CGI demo 6 | ''' 7 | 8 | import cgi 9 | 10 | header = 'Content-Type: text/html\n\n' 11 | 12 | formhtml = '''Friends CGI Demo 13 |

Friends list for: NEW USER

14 |
15 | Enter your Name: 16 | 17 | 18 |

How many friends do you have? 19 | %s 20 |

''' 21 | 22 | friendradio = ' %s\n' 23 | 24 | def showForm(): 25 | friends = '' 26 | for i in [0, 10, 25, 50, 100]: 27 | checked = '' 28 | if i == 0: 29 | checked = 'CHECKED' 30 | friends = friends + friendradio % (str(i), checked, str(i)) 31 | print header + formhtml % (friends) 32 | 33 | 34 | reshtml = '''Friends CGI Demo 35 |

Friends list for: %s

36 | Your name is: %s

37 | You have %s friends. 38 | ''' 39 | 40 | def doResults(who, howmany): 41 | # substitute in real name and number of friends and return 42 | print header + reshtml % (who, who, howmany) 43 | 44 | 45 | # process() does all the work 46 | def process(): 47 | 48 | # initialize Data class object 49 | form = cgi.FieldStorage() 50 | 51 | # get user name 52 | if form.has_key('person'): 53 | who = form['person'].value 54 | else: 55 | who = 'NEW USER' 56 | 57 | # get name and number of friends 58 | if form.has_key('howmany'): 59 | howmany = form['howmany'].value 60 | else: 61 | howmany = 0 62 | 63 | # if editing, show results 64 | if form.has_key('action'): 65 | doResults(who, howmany) 66 | 67 | # otherwise, show form 68 | else: 69 | showForm() 70 | 71 | # invoke if called directly 72 | if __name__ == '__main__': 73 | process() 74 | -------------------------------------------------------------------------------- /ch10/alt/cardrun.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id$ 4 | 5 | cardrun.py -- "credit card run" script serves as a demo for a 6 | ficticious credit card transaction processing application 7 | which reads data in from a file and uses the safe_float() 8 | function along with try-except to safely "ignore bad data" 9 | such as string text as opposed to strictly numerical input. 10 | ''' 11 | 12 | # safe_float() --> float 13 | def safe_float(object): 14 | 'safe_float() converts strings to floats "safely"' 15 | 16 | # attempt to convert object using float() 17 | try: 18 | retval = float(object) 19 | 20 | # failure return value is error reason 21 | except (TypeError, ValueError), e: 22 | retval = str(e) 23 | 24 | return retval 25 | 26 | 27 | # main() --> None 28 | def main(): 29 | 'main() handles all the data processing' 30 | 31 | # attempt to open data file 32 | try: 33 | ccfile = open('carddata.txt', 'r') 34 | 35 | # display error reason on failure 36 | except IOError, e: 37 | print 'file open failed:', e 38 | return 39 | 40 | # otherwise show a diagnostic 'ok' 41 | else: 42 | print 'file opened successfully' 43 | 44 | # read all data and close file 45 | txns = ccfile.readlines() 46 | ccfile.close() 47 | 48 | # processing setup 49 | total = 0.00 50 | print 'processing new account, log:' 51 | 52 | # look at each transaction 53 | for eachTxn in txns: 54 | result = safe_float(eachTxn) 55 | 56 | # string indicates failure ... 57 | if isinstance(result, basestring): 58 | if eachTxn[0] == '#': 59 | print 'comment... ignored' 60 | else: 61 | print '\ncategory:', eachTxn 62 | 63 | # ... while float means success 64 | elif isinstance(result, float): 65 | total += result 66 | print 'processing transaction of: %.2f' % result 67 | 68 | # unknown return type from safe_float() 69 | else: 70 | print 'invalid return type from safe_float()... ignored' 71 | 72 | # display final totals 73 | print 'new balance: $%.2f' % (total) 74 | 75 | # call main() if invoked as script 76 | if __name__ == '__main__': 77 | main() 78 | -------------------------------------------------------------------------------- /ch06/alt/stack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id$ 4 | 5 | stack.py -- simulate stack data structures using lists 6 | 7 | Exercises: 8 | 9 | 13-8) create a Stack class 10 | 11 | 13-10) create a class similar to arrays in Perl which have 12 | both queue- and stack-like qualities and features 13 | ''' 14 | 15 | # create our data structure 16 | stack = [] 17 | 18 | # 19 | # pushit() -- adds stirng to the stack 20 | # 21 | def pushit(): 22 | stack.append(raw_input('Enter new string: ')) 23 | 24 | # 25 | # popit() -- removes stirng from the stack 26 | # 27 | def popit(): 28 | if len(stack) == 0: 29 | print 'Cannot pop from an empty stack!' 30 | else: 31 | print 'Removed [', stack.pop(), ']' 32 | 33 | # 34 | # viewstack() -- display stack contents 35 | # 36 | def viewstack(): 37 | print str(stack) 38 | 39 | # 40 | # showmenu() -- interactive portion of application 41 | # displays menu to prompt user and takes 42 | # action based on user response 43 | # 44 | def showmenu(): 45 | 46 | # using triple quotes to help us put together 47 | # the multi-line string prompt to display 48 | prompt = """ 49 | p(U)sh 50 | p(O)p 51 | (V)iew 52 | (Q)uit 53 | 54 | Enter choice: """ 55 | 56 | # loop until user quits 57 | done = 0 58 | while not done: 59 | 60 | # loop until user choses valid option 61 | chosen = 0 62 | while not chosen: 63 | 64 | # if user hits RETURN/Enter, ^C, or ^D (EOF), 65 | # pretend they typed 'q' to quit normally 66 | try: 67 | choice = raw_input(prompt)[0] 68 | except (IndexError, EOFError, KeyboardInterrupt): 69 | choice = 'q' 70 | print '\nYou picked: [%s]' % choice 71 | 72 | # validate option chosen 73 | if choice not in 'uovq': 74 | print 'invalid option, try again' 75 | else: 76 | chosen = 1 77 | 78 | # take appropriate action 79 | if choice == 'q': 80 | done = 1 81 | if choice == 'u': 82 | pushit() 83 | if choice == 'o': 84 | popit() 85 | if choice == 'v': 86 | viewstack() 87 | 88 | # run showmenu() as the application 89 | if __name__ == '__main__': 90 | showmenu() 91 | -------------------------------------------------------------------------------- /ch06/alt/queue.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id$ 4 | 5 | queue.py -- simulate queue data structures using lists 6 | 7 | NOTE: as of the time of publication, there is a bug in JPython1.1 8 | that does not recognize arguments for the list pop() method: 9 | TypeError: pop(): expected 0 args; got 1 10 | 11 | Exercises: 12 | 13 | 13-9) create a Queue class 14 | 15 | 13-10) create a class similar to arrays in Perl which have 16 | both queue- and stack-like qualities and features 17 | ''' 18 | 19 | # create our data structure 20 | queue = [] 21 | 22 | # 23 | # enQ() -- add string to end of queue 24 | # 25 | def enQ(): 26 | queue.append(raw_input('Enter new queue element: ')) 27 | 28 | # 29 | # deQ() -- remove string from front of queue 30 | # 31 | def deQ(): 32 | if len(queue) == 0: 33 | print 'Cannot dequeue from empty queue!' 34 | else: 35 | print 'Removed [', queue.pop(0), ']' 36 | 37 | # 38 | # viewQ() -- display queue contents 39 | # 40 | def viewQ(): 41 | print str(queue) 42 | 43 | # 44 | # showmenu() -- interactive portion of application 45 | # displays menu to prompt user and takes 46 | # action based on user response 47 | # 48 | def showmenu(): 49 | prompt = """ 50 | (E)nqueue 51 | (D)equeue 52 | (V)iew 53 | (Q)uit 54 | 55 | Enter choice: """ 56 | 57 | # loop until user quits 58 | done = 0 59 | while not done: 60 | 61 | # loop until user choses valid option 62 | chosen = 0 63 | while not chosen: 64 | 65 | # if user hits ^C or ^D (EOF), 66 | # pretend they typed 'q' to quit 67 | try: 68 | choice = raw_input(prompt)[0] 69 | except (IndexError, EOFError, KeyboardInterrupt): 70 | choice = 'q' 71 | print '\nYou picked: [%s]' % choice 72 | 73 | # validate option chosen 74 | if choice not in 'devq': 75 | print 'invalid option, try again' 76 | else: 77 | chosen = 1 78 | 79 | # take appropriate action 80 | if choice == 'q': 81 | done = 1 82 | if choice == 'e': 83 | enQ() 84 | if choice == 'd': 85 | deQ() 86 | if choice == 'v': 87 | viewQ() 88 | 89 | # run showmenu() as the application 90 | if __name__ == '__main__': 91 | showmenu() 92 | -------------------------------------------------------------------------------- /ch20/friends3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import cgi 4 | from urllib import quote_plus 5 | from string import capwords 6 | 7 | header = 'Content-Type: text/html\n\n' 8 | url = '/cgi-bin/friends3.py' 9 | 10 | errhtml = ''' 11 | Friends CGI Demo 12 |

ERROR

13 | %s

14 |

16 | ''' 17 | 18 | def showError(error_str): 19 | print header + errhtml % (error_str) 20 | 21 | formhtml = ''' 22 | Friends CGI Demo 23 |

Friends list for: %s

24 |
25 | Your Name: 26 | 27 | 28 |

How many friends do you have? 29 | %s 30 |

''' 31 | 32 | fradio = ' %s\n' 33 | 34 | def showForm(who, howmany): 35 | friends = '' 36 | for i in [0, 10, 25, 50, 100]: 37 | checked = '' 38 | if str(i) == howmany: 39 | checked = 'CHECKED' 40 | friends = friends + fradio % \ 41 | (str(i), checked, str(i)) 42 | print header + formhtml % (who, url, who, friends) 43 | 44 | reshtml = ''' 45 | Friends CGI Demo 46 |

Friends list for: %s

47 | Your name is: %s

48 | You have %s friends. 49 |

Click here to edit your data again. 50 | ''' 51 | 52 | def doResults(who, howmany): 53 | newurl = url + '?action=reedit&person=%s&howmany=%s' % \ 54 | (quote_plus(who), howmany) 55 | print header + reshtml % (who, who, howmany, newurl) 56 | 57 | def process(): 58 | error = '' 59 | form = cgi.FieldStorage() 60 | 61 | if form.has_key('person'): 62 | who = capwords(form['person'].value) 63 | else: 64 | who = 'NEW USER' 65 | 66 | if form.has_key('howmany'): 67 | howmany = form['howmany'].value 68 | else: 69 | if form.has_key('action') and \ 70 | form['action'].value == 'edit': 71 | error = 'Please select number of friends.' 72 | else: 73 | howmany = 0 74 | 75 | if not error: 76 | if form.has_key('action') and \ 77 | form['action'].value != 'reedit': 78 | doResults(who, howmany) 79 | else: 80 | showForm(who, howmany) 81 | else: 82 | showError(error) 83 | 84 | if __name__ == '__main__': 85 | process() 86 | -------------------------------------------------------------------------------- /ch17/getLatestNNTP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import nntplib 4 | import socket 5 | 6 | HOST = 'your.nntp.sersper' 7 | GRNM = 'comp.lang.python' 8 | USER = 'wesley' 9 | PASS = "you'llNeverGuess" 10 | 11 | def main(): 12 | 13 | try: 14 | n = nntplib.NNTP(HOST) 15 | #user=USER, password=PASS) 16 | except socket.gaierror, e: 17 | print 'ERROR: cannot reach host "%s"' % HOST 18 | print ' ("%s")' % eval(str(e))[1] 19 | return 20 | except nntplib.NNTPPermanentError, e: 21 | print 'ERROR: access denied on "%s"' % HOST 22 | print ' ("%s")' % str(e) 23 | return 24 | print '*** Connected to host "%s"' % HOST 25 | 26 | try: 27 | rsp, ct, fst, lst, grp = n.group(GRNM) 28 | except nntplib.NNTPTemporaryError, e: 29 | print 'ERROR: cannot connect to group "%s"' % GRNM 30 | print ' ("%s")' % str(e) 31 | print ' Server may require authentication' 32 | print ' Uncomment/edit login line above' 33 | n.quit() 34 | return 35 | except nntplib.NNTPTemporaryError, e: 36 | print 'ERROR: group "%s" unavailable' % GRNM 37 | print ' ("%s")' % str(e) 38 | n.quit() 39 | return 40 | print '*** Found newsgroup "%s"' % GRNM 41 | 42 | rng = '%s-%s' % (lst, lst) 43 | rsp, frm = n.xhdr('from', rng) 44 | rsp, sub = n.xhdr('subject', rng) 45 | rsp, dat = n.xhdr('date', rng) 46 | print '''*** Found last article (#%s): 47 | 48 | From: %s 49 | Subject: %s 50 | Date: %s 51 | '''% (lst, frm[0][1], sub[0][1], dat[0][1]) 52 | 53 | rsp, anum, mid, data = n.body(lst) 54 | displayFirst20(data) 55 | n.quit() 56 | 57 | def displayFirst20(data): 58 | print '*** First (<= 20) meaningful lines:\n' 59 | count = 0 60 | lines = (line.rstrip() for line in data) 61 | lastBlank = True 62 | for line in lines: 63 | if line: 64 | lower = line.lower() 65 | if (lower.startswith('>') and not \ 66 | lower.startswith('>>>')) or \ 67 | lower.startswith('|') or \ 68 | lower.startswith('in article') or \ 69 | lower.endswith('writes:') or \ 70 | lower.endswith('wrote:'): 71 | continue 72 | if not lastBlank or (lastBlank and line): 73 | print ' %s' % line 74 | if line: 75 | count += 1 76 | lastBlank = False 77 | else: 78 | lastBlank = True 79 | if count == 20: 80 | break 81 | 82 | if __name__ == '__main__': 83 | main() 84 | -------------------------------------------------------------------------------- /ch10/myexc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os, socket, errno, types, tempfile 4 | 5 | class NetworkError(IOError): 6 | pass 7 | 8 | class FileError(IOError): 9 | pass 10 | 11 | def updArgs(args, newarg=None): 12 | if isinstance(args, IOError): 13 | myargs = [] 14 | myargs.extend([arg for arg in args]) 15 | else: 16 | myargs = list(args) 17 | 18 | if newarg: 19 | myargs.append(newarg) 20 | 21 | return tuple(myargs) 22 | 23 | def fileArgs(fn, mode, args): 24 | if args[0] == errno.EACCES and \ 25 | 'access' in dir(os): 26 | perms = '' 27 | permd = {'r': os.R_OK, 'w': os.W_OK, 28 | 'x': os.X_OK} 29 | pkeys = permd.keys() 30 | pkeys.sort() 31 | pkeys.reverse() 32 | 33 | for eachPerm in 'rwx': 34 | if os.access(fn, permd[eachPerm]): 35 | perms = perms + eachPerm 36 | else: 37 | perms = perms + '-' 38 | 39 | if isinstance(args, IOError): 40 | myargs = [] 41 | myargs.extend([arg for arg in args]) 42 | else: 43 | myargs = list(args) 44 | 45 | myargs[1] = "'%s' %s (perms: '%s')" % \ 46 | (mode, myargs[1], perms) 47 | 48 | myargs.append(args.filename) 49 | 50 | else: 51 | myargs = args 52 | 53 | return tuple(myargs) 54 | 55 | def myconnect(sock, host, port): 56 | try: 57 | sock.connect((host, port)) 58 | 59 | except socket.error, args: 60 | myargs = updArgs(args) # convert inst to tuple 61 | if len(myargs) == 1: # no #s on some errors 62 | myargs = (errno.ENXIO, myargs[0]) 63 | 64 | raise NetworkError, \ 65 | updArgs(myargs, host + ':' + str(port)) 66 | 67 | def myopen(fn, mode='r'): 68 | try: 69 | fo = open(fn, mode) 70 | except IOError, args: 71 | raise FileError, fileArgs(fn, mode, args) 72 | 73 | return fo 74 | 75 | def testfile(): 76 | 77 | fn = tempfile.mktemp() 78 | f = open(fn, 'w') 79 | f.close() 80 | 81 | for eachTest in ((0, 'r'), (0100, 'r'), \ 82 | (0400, 'w'), (0500, 'w')): 83 | try: 84 | os.chmod(fn, eachTest[0]) 85 | f = myopen(fn, eachTest[1]) 86 | 87 | except FileError, args: 88 | print "%s: %s" % \ 89 | (args.__class__.__name__, args) 90 | else: 91 | print fn, "opened ok... perms ignored" 92 | f.close() 93 | 94 | os.chmod(fn, 0777) # enable all perms 95 | os.unlink(fn) 96 | 97 | def testnet(): 98 | s = socket.socket(socket.AF_INET, 99 | socket.SOCK_STREAM) 100 | 101 | for eachHost in (YOUR HOSTS HERE) 102 | try: 103 | myconnect(s, eachHost, 80) 104 | except NetworkError, args: 105 | print "%s: %s" % \ 106 | (args.__class__.__name__, args) 107 | 108 | if __name__ == '__main__': 109 | testfile() 110 | testnet() 111 | -------------------------------------------------------------------------------- /ch07/alt/userpw.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id$ 4 | 5 | userpw.py -- maintain a "user database" consisting of a set 6 | of login names and corresponding passwords 7 | 8 | Exercises: 9 | 10 | 7-5a) add a timestamp to the data stored so that the 11 | user is informed of last successful login 12 | 13 | 7-5b) add an "administrative user" which can remove 14 | users from the database as well as view the 15 | entire list of current users 16 | 17 | 7-5c) add a level of security by encrypting passwords 18 | 19 | 7-5d) at a GUI interface if you are familiar with one 20 | such as Tkinter 21 | 22 | 9-13a) store the data base to a disk file so that you 23 | do not have to "recreate" the database every 24 | time you run your application 25 | 26 | 9-13b) use the pickle module to store the database 27 | object directly as opposed to writing out the 28 | data one line at a time 29 | ''' 30 | # clear database dictionary 31 | db = {} 32 | 33 | # 34 | # newuser() -- create new user and add to database 35 | # 36 | def newuser(): 37 | prompt = 'login desired: ' 38 | while 1: 39 | name = raw_input(prompt) 40 | if db.has_key(name): 41 | prompt = 'name taken, try another: ' 42 | continue 43 | else: 44 | break 45 | pwd = raw_input('passwd: ') 46 | db[name] = pwd 47 | 48 | 49 | # 50 | # olduser() -- verify password to login existing users 51 | # 52 | def olduser(): 53 | name = raw_input('login: ') 54 | pwd = raw_input('passwd: ') 55 | passwd = db.get(name) 56 | if passwd == pwd: 57 | pass 58 | else: 59 | print 'login incorrect' 60 | return 61 | 62 | print 'welcome back', name 63 | 64 | 65 | # 66 | # showmenu() -- interactive portion of application 67 | # displays menu to prompt user and takes 68 | # action based on user response 69 | # 70 | def showmenu(): 71 | prompt = """ 72 | (N)ew User Login 73 | (E)xisting User Login 74 | (Q)uit 75 | 76 | Enter choice: """ 77 | 78 | # loop until user quits 79 | done = 0 80 | while not done: 81 | 82 | # loop until user choses valid option 83 | chosen = 0 84 | while not chosen: 85 | 86 | # if user hits RETURN/Enter, ^C, or ^D (EOF), 87 | # pretend they typed 'q' to quit normally 88 | try: 89 | choice = raw_input(prompt)[0] 90 | except (EOFError, KeyboardInterrupt): 91 | choice = 'q' 92 | print '\nYou picked: [%s]' % choice 93 | 94 | # validate option chosen 95 | if choice not in 'neq': 96 | print 'invalid menu option, try again' 97 | else: 98 | chosen = 1 99 | 100 | # take appropriate action 101 | if choice == 'q': 102 | done = 1 103 | if choice == 'n': 104 | newuser() 105 | if choice == 'e': 106 | olduser() 107 | 108 | 109 | # run showmenu() as the application 110 | if __name__ == '__main__': 111 | showmenu() 112 | -------------------------------------------------------------------------------- /ch09/alt/ospathex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id$ 4 | 5 | ospathex.py -- OS path example 6 | 7 | This script test drives many of the operating system module file 8 | and file path functions. The temporary directory is chosen by 9 | the tempfile module. If that does not exist, then there is a 10 | limited set of directory names that are hard-coded as part of 11 | this application. Please add one for your system if this script 12 | cannot find a temporary directory for you. 13 | ''' 14 | 15 | import os # operating system module (import real OS module, i.e., posix, nt, etc.) 16 | 17 | def testOSmod(tmpdir): 18 | 'testOSmod(tmpdir) -- test the "os" module with given temporary directory' 19 | 20 | # set working directory 21 | wd = os.path.join(tmpdir, 'example') 22 | 23 | # create and display test subdirectory name 24 | print '*** creating example directory...' 25 | os.mkdir(wd) 26 | print '*** new working directory:' 27 | print wd 28 | 29 | # display test subdirectory listing 30 | print '*** working directory listing:' 31 | print os.listdir(wd) 32 | 33 | # create test file and show updated directory listing 34 | print '*** creating test file...' 35 | testfile = os.path.join(wd, 'test') 36 | file = open(testfile, 'w') 37 | file.write('foo\n') 38 | file.write('bar\n') 39 | file.close() 40 | print '*** updated directory listing:' 41 | print os.listdir(wd) 42 | 43 | # test file rename using os.rename() 44 | print "*** renaming 'test' to 'filetest.txt'" 45 | newtestfile = os.path.join(wd, 'filetest.txt') 46 | os.rename(testfile, newtestfile) 47 | print '*** updated directory listing:' 48 | print os.listdir(wd) 49 | 50 | # test file pathname component join function (os.path.join()) 51 | # (join directory name and only file [our test file] in directory) 52 | path = os.path.join(wd, os.listdir(wd)[0]) 53 | print '*** full file pathname:' 54 | print path 55 | 56 | # test file pathname split and extension split 57 | print '*** (pathname, basename) == ' 58 | print os.path.split(path) 59 | print '*** (filename, extension) == ' 60 | print os.path.splitext(os.path.basename(path)) 61 | 62 | # display test file contents 63 | print '*** displaying file contents:' 64 | file = open(path) 65 | allLines = file.readlines() 66 | file.close() 67 | for eachLine in allLines: 68 | print eachLine, 69 | 70 | # remove test file, show updated directory listing 71 | print '*** deleting test file' 72 | os.remove(path) 73 | print '*** updated directory listing:' 74 | print os.listdir(wd) 75 | 76 | # delete test directory 77 | print '*** deleting test directory' 78 | os.rmdir(wd) 79 | print '*** DONE' 80 | 81 | 82 | def main(): 83 | 'main() -- look for temporary directory and run test' 84 | 85 | # look for a temporary directory; try tempfile module first 86 | try: 87 | from tempfile import gettempdir 88 | tmpdir = gettempdir() 89 | 90 | # if tempfile not available, try a few selected directories 91 | except: 92 | for tmpdir in ('/tmp', 'c:/windows/temp'): 93 | if os.path.isdir(tmpdir): 94 | break 95 | 96 | # otherwise no temporary directory found 97 | else: 98 | print 'no temp directory available' 99 | return 100 | 101 | testOSmod(tmpdir) 102 | 103 | 104 | # run main() if invoked as script 105 | if __name__ == '__main__': 106 | main() 107 | -------------------------------------------------------------------------------- /ch21/ushuffle_so.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | from random import randrange as rrange 5 | from sqlobject import * 6 | from ushuffle_db import NAMES, randName 7 | 8 | DBNAME = 'test' 9 | COLSIZ = 10 10 | FIELDS = ('login', 'uid', 'prid') 11 | 12 | class MySQLObject(object): 13 | def __init__(self, db, dbName): 14 | import MySQLdb 15 | import _mysql_exceptions 16 | url = 'mysql://localhost/%s' % DBNAME 17 | 18 | while True: 19 | cxn = connectionForURI(url) 20 | sqlhub.processConnection = cxn 21 | #cxn.debug = True 22 | try: 23 | class Users(SQLObject): 24 | class sqlmeta: 25 | fromDatabase = True 26 | login = StringCol(length=8) 27 | uid = IntCol() 28 | prid = IntCol() 29 | break 30 | except _mysql_exceptions.ProgrammingError, e: 31 | class Users(SQLObject): 32 | login = StringCol(length=8) 33 | uid = IntCol() 34 | prid = IntCol() 35 | break 36 | except _mysql_exceptions.OperationalError, e: 37 | cxn1 = sqlhub.processConnection=connectionForURI('mysql://root@localhost') 38 | cxn1.query("CREATE DATABASE %s" % DBNAME) 39 | cxn1.query("GRANT ALL ON %s.* TO ''@'localhost'" % DBNAME) 40 | cxn1.close() 41 | self.users = Users 42 | self.cxn = cxn 43 | 44 | def create(self): 45 | Users = self.users 46 | Users.dropTable(True) 47 | Users.createTable() 48 | 49 | def insert(self): 50 | for who, uid in randName(): 51 | self.users(**dict(zip(FIELDS, 52 | [who, uid, rrange(1,5)]))) 53 | 54 | def update(self): 55 | fr = rrange(1,5) 56 | to = rrange(1,5) 57 | users = self.users.selectBy(prid=fr) 58 | for i, user in enumerate(users): 59 | user.prid = to 60 | return fr, to, i+1 61 | 62 | def delete(self): 63 | rm = rrange(1,5) 64 | users = self.users.selectBy(prid=rm) 65 | for i, user in enumerate(users): 66 | user.destroySelf() 67 | return rm, i+1 68 | 69 | def dbDump(self): 70 | print '\n%s%s%s' % ('LOGIN'.ljust(COLSIZ), 71 | 'USERID'.ljust(COLSIZ), 'PROJ#'.ljust(COLSIZ)) 72 | for usr in self.users.select(): 73 | print '%s%s%s' % (tuple([str(getattr(usr, 74 | field)).title().ljust(COLSIZ) \ 75 | for field in FIELDS])) 76 | 77 | drop = lambda self: self.users.dropTable() 78 | finish = lambda self: self.cxn.close() 79 | 80 | def main(): 81 | print '*** Connecting to %r database' % DBNAME 82 | orm = MySQLObject('mysql', DBNAME) 83 | 84 | print '\n*** Creating users table' 85 | orm.create() 86 | 87 | print '\n*** Inserting names into table' 88 | orm.insert() 89 | orm.dbDump() 90 | 91 | print '\n*** Randomly moving folks', 92 | fr, to, num = orm.update() 93 | print 'from one group (%d) to another (%d)' % (fr, to) 94 | print '\t(%d users moved)' % num 95 | orm.dbDump() 96 | 97 | print '\n*** Randomly choosing group', 98 | rm, num = orm.delete() 99 | print '(%d) to delete' % rm 100 | print '\t(%d users removed)' % num 101 | orm.dbDump() 102 | 103 | print '\n*** Dropping users table' 104 | orm.drop() 105 | orm.finish() 106 | 107 | if __name__ == '__main__': 108 | main() 109 | -------------------------------------------------------------------------------- /ch21/ushuffle_sa.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | from random import randrange as rrange 5 | from sqlalchemy import * 6 | from ushuffle_db import NAMES, randName 7 | 8 | FIELDS = ('login', 'uid', 'prid') 9 | DBNAME = 'test' 10 | COLSIZ = 10 11 | 12 | class MySQLAlchemy(object): 13 | def __init__(self, db, dbName): 14 | import MySQLdb 15 | import _mysql_exceptions 16 | MySQLdb = pool.manage(MySQLdb) 17 | url = 'mysql://db=%s' % DBNAME 18 | eng = create_engine(url) 19 | try: 20 | cxn = eng.connection() 21 | except _mysql_exceptions.OperationalError, e: 22 | eng1 = create_engine('mysql://user=root') 23 | try: 24 | eng1.execute('DROP DATABASE %s' % DBNAME) 25 | except _mysql_exceptions.OperationalError, e: 26 | pass 27 | eng1.execute('CREATE DATABASE %s' % DBNAME) 28 | eng1.execute( 29 | "GRANT ALL ON %s.* TO ''@'localhost'" % DBNAME) 30 | eng1.commit() 31 | cxn = eng.connection() 32 | 33 | try: 34 | users = Table('users', eng, autoload=True) 35 | except exceptions.SQLError, e: 36 | users = Table('users', eng, 37 | Column('login', String(8)), 38 | Column('uid', Integer), 39 | Column('prid', Integer), 40 | redefine=True) 41 | 42 | self.eng = eng 43 | self.cxn = cxn 44 | self.users = users 45 | 46 | def create(self): 47 | users = self.users 48 | try: 49 | users.drop() 50 | except exceptions.SQLError, e: 51 | pass 52 | users.create() 53 | 54 | def insert(self): 55 | d = [dict(zip(FIELDS, 56 | [who, uid, rrange(1,5)])) for who, uid in randName()] 57 | return self.users.insert().execute(*d).rowcount 58 | 59 | def update(self): 60 | users = self.users 61 | fr = rrange(1,5) 62 | to = rrange(1,5) 63 | return fr, to, \ 64 | users.update(users.c.prid==fr).execute(prid=to).rowcount 65 | 66 | def delete(self): 67 | users = self.users 68 | rm = rrange(1,5) 69 | return rm, \ 70 | users.delete(users.c.prid==rm).execute().rowcount 71 | 72 | def dbDump(self): 73 | res = self.users.select().execute() 74 | print '\n%s%s%s' % ('LOGIN'.ljust(COLSIZ), 75 | 'USERID'.ljust(COLSIZ), 'PROJ#'.ljust(COLSIZ)) 76 | for data in res.fetchall(): 77 | print '%s%s%s' % tuple([str(s).title().ljust(COLSIZ) for s in data]) 78 | 79 | def __getattr__(self, attr): 80 | return getattr(self.users, attr) 81 | 82 | def finish(self): 83 | self.cxn.commit() 84 | self.eng.commit() 85 | 86 | def main(): 87 | print '*** Connecting to %r database' % DBNAME 88 | orm = MySQLAlchemy('mysql', DBNAME) 89 | 90 | print '\n*** Creating users table' 91 | orm.create() 92 | 93 | print '\n*** Inserting names into table' 94 | orm.insert() 95 | orm.dbDump() 96 | 97 | print '\n*** Randomly moving folks', 98 | fr, to, num = orm.update() 99 | print 'from one group (%d) to another (%d)' % (fr, to) 100 | print '\t(%d users moved)' % num 101 | orm.dbDump() 102 | 103 | print '\n*** Randomly choosing group', 104 | rm, num = orm.delete() 105 | print '(%d) to delete' % rm 106 | print '\t(%d users removed)' % num 107 | orm.dbDump() 108 | 109 | print '\n*** Dropping users table' 110 | orm.drop() 111 | orm.finish() 112 | 113 | if __name__ == '__main__': 114 | main() 115 | -------------------------------------------------------------------------------- /ch20/alt/friends3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id: friends3.py,v 1.1 2000/12/31 01:32:45 wesc Exp $ 4 | 5 | Friends CGI demo 6 | ''' 7 | 8 | import cgi 9 | from urllib import quote_plus 10 | from string import capwords 11 | #from sys import stderr 12 | #s = stderr.write 13 | 14 | header = 'Content-Type: text/html\n\n' 15 | url = 'http://localhost/cgi-bin/friends3.py' 16 | 17 | errhtml = '''Friends CGI Demo 18 |

ERROR

19 | %s

20 |

21 | ''' 22 | 23 | # showError() --> None 24 | def showError(error_str): 25 | 'showError() -- display error message' 26 | print header + errhtml % (error_str) 27 | 28 | friendradio = ' %s\n' 29 | 30 | formhtml = '''Friends CGI Demo 31 |

Friends list for: %s

32 |
33 | Your Name: 34 | 35 | 36 |

How many friends do you have? 37 | %s 38 |

''' 39 | 40 | # showForm() --> None 41 | def showForm(who, howmany): 42 | 'showForm() -- presents blank or data-filled form for new input' 43 | 44 | friends = '' 45 | for i in [0, 10, 25, 50, 100]: 46 | checked = '' 47 | if str(i) == howmany: 48 | checked = 'CHECKED' 49 | friends = friends + friendradio % (str(i), checked, str(i)) 50 | print header + formhtml % (who, url, who, friends) 51 | 52 | reshtml = '''Friends CGI Demo 53 |

Friends list for: %s

54 | Your name is: %s

55 | You have %s friends. 56 |

Click here to edit your data again. 57 | ''' 58 | 59 | # doResults() --> None 60 | def doResults(who, howmany): 61 | 'doResults() -- displays results with given form data' 62 | 63 | # substitute in real name and number of friends and return 64 | newurl = url + '?action=reedit&person=%s&howmany=%s' % (quote_plus(who), howmany) 65 | print header + reshtml % (who, who, howmany, newurl) 66 | 67 | # process() --> None 68 | def process(): 69 | 'process() does all the work: grabs user data and determines routine to call' 70 | 71 | error = '' 72 | 73 | # initialize Data class object 74 | form = cgi.FieldStorage() 75 | #s('name: '+str(form.name)+'\n') 76 | #s('keys: '+str(form.keys())+'\n') 77 | #for i in form.keys(): 78 | #s('item: '+str(form[i].name)+' has a value of '+str(form[i].value)+' and is a ' + form[i].__class__.__name__ + '\n') 79 | 80 | # get user name 81 | if form.has_key('person'): 82 | who = capwords(form['person'].value) 83 | else: 84 | who = 'NEW USER' 85 | 86 | # get name and number of friends 87 | if form.has_key('howmany'): 88 | howmany = form['howmany'].value 89 | else: 90 | if form.has_key('action') and form['action'].value == 'edit': 91 | error = 'Please select the number of friends you have.' 92 | else: 93 | howmany = 0 94 | 95 | # no errors, either display form or present results 96 | if not error: 97 | 98 | # if editing the first time, show results 99 | if form.has_key('action') and form['action'].value != 'reedit': 100 | doResults(who, howmany) 101 | 102 | # otherwise, show form 103 | else: 104 | showForm(who, howmany) 105 | 106 | # send error message back if error situation 107 | else: 108 | showError(error) 109 | 110 | 111 | # invoke if called directly 112 | if __name__ == '__main__': 113 | process() 114 | -------------------------------------------------------------------------------- /ch19/listdir.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | from time import sleep 5 | from Tkinter import * 6 | 7 | class DirList: 8 | 9 | def __init__(self, initdir=None): 10 | self.top = Tk() 11 | self.label = Label(self.top, \ 12 | text='Directory Lister' + ' v1.1') 13 | self.label.pack() 14 | 15 | self.cwd=StringVar(self.top) 16 | 17 | self.dirl = Label(self.top, fg='blue', 18 | font=('Helvetica', 12, 'bold')) 19 | self.dirl.pack() 20 | 21 | self.dirfm = Frame(self.top) 22 | self.dirsb = Scrollbar(self.dirfm) 23 | self.dirsb.pack(side=RIGHT, fill=Y) 24 | self.dirs = Listbox(self.dirfm, height=15, \ 25 | width=50, yscrollcommand=self.dirsb.set) 26 | self.dirs.bind('', self.setdirandgo) 27 | self.dirsb.config(command=self.dirs.yview) 28 | self.dirs.pack(side=LEFT, fill=BOTH) 29 | self.dirfm.pack() 30 | 31 | self.dirn = Entry(self.top, width=50, \ 32 | textvariable=self.cwd) 33 | self.dirn.bind('', self.dols) 34 | self.dirn.pack() 35 | 36 | self.bfm = Frame(self.top) 37 | self.clr = Button(self.bfm, text='Clear', \ 38 | command=self.clrdir, \ 39 | activeforeground='white', \ 40 | activebackground='blue') 41 | self.ls = Button(self.bfm, \ 42 | text='List Directory', \ 43 | command=self.dols, \ 44 | activeforeground='white', \ 45 | activebackground='green') 46 | self.quit = Button(self.bfm, text='Quit', \ 47 | command=self.top.quit, \ 48 | activeforeground='white', \ 49 | activebackground='red') 50 | self.clr.pack(side=LEFT) 51 | self.ls.pack(side=LEFT) 52 | self.quit.pack(side=LEFT) 53 | self.bfm.pack() 54 | 55 | if initdir: 56 | self.cwd.set(os.curdir) 57 | self.dols() 58 | 59 | def clrdir(self, ev=None): 60 | self.cwd.set('') 61 | 62 | def setdirandgo(self, ev=None): 63 | self.last = self.cwd.get() 64 | self.dirs.config(selectbackground='red') 65 | check = self.dirs.get(self.dirs.curselection()) 66 | if not check: 67 | check = os.curdir 68 | self.cwd.set(check) 69 | self.dols() 70 | 71 | def dols(self, ev=None): 72 | error = '' 73 | tdir = self.cwd.get() 74 | if not tdir: tdir = os.curdir 75 | 76 | if not os.path.exists(tdir): 77 | error = tdir + ': no such file' 78 | elif not os.path.isdir(tdir): 79 | error = tdir + ': not a directory' 80 | 81 | if error: 82 | self.cwd.set(error) 83 | self.top.update() 84 | sleep(2) 85 | if not (hasattr(self, 'last') \ 86 | and self.last): 87 | self.last = os.curdir 88 | self.cwd.set(self.last) 89 | self.dirs.config( \ 90 | selectbackground='LightSkyBlue') 91 | self.top.update() 92 | return 93 | 94 | self.cwd.set( \ 95 | 'FETCHING DIRECTORY CONTENTS...') 96 | self.top.update() 97 | dirlist = os.listdir(tdir) 98 | dirlist.sort() 99 | os.chdir(tdir) 100 | self.dirl.config(text=os.getcwd()) 101 | self.dirs.delete(0, END) 102 | self.dirs.insert(END, os.curdir) 103 | self.dirs.insert(END, os.pardir) 104 | for eachFile in dirlist: 105 | self.dirs.insert(END, eachFile) 106 | self.cwd.set(os.curdir) 107 | self.dirs.config( \ 108 | selectbackground='LightSkyBlue') 109 | 110 | def main(): 111 | d = DirList(os.curdir) 112 | mainloop() 113 | 114 | if __name__ == '__main__': 115 | main() 116 | -------------------------------------------------------------------------------- /ch20/crawl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from sys import argv 4 | from os import makedirs, unlink, sep 5 | from os.path import isdir, exists, dirname, splitext 6 | from string import replace, find, lower 7 | from htmllib import HTMLParser 8 | from urllib import urlretrieve 9 | from urlparse import urlparse, urljoin 10 | from formatter import DumbWriter, AbstractFormatter 11 | from cStringIO import StringIO 12 | 13 | class Retriever(object): # download Web pages 14 | 15 | def __init__(self, url): 16 | self.url = url 17 | self.file = self.filename(url) 18 | 19 | def filename(self, url, deffile='index.htm'): 20 | parsedurl = urlparse(url, 'http:', 0) # parse path 21 | path = parsedurl[1] + parsedurl[2] 22 | ext = splitext(path) 23 | if ext[1] == '': 24 | if path[-1] == '/': 25 | path += deffile 26 | else: 27 | path += '/' + deffile 28 | ldir = dirname(path) # local directory 29 | if sep != '/': # os-indep. path separator 30 | ldir = replace(ldir, ',', sep) 31 | if not isdir(ldir): # create archive dir if nec. 32 | if exists(ldir): unlink(ldir) 33 | makedirs(ldir) 34 | return path 35 | 36 | def download(self): # download Web page 37 | try: 38 | retval = urllib.urlretrieve(self.url, self.file) 39 | except IOError: 40 | retval = ('*** ERROR: invalid URL "%s"' % \ 41 | self.url, ) 42 | return retval 43 | 44 | def parseAndGetLinks(self): # pars HTML, save links 45 | self.parser = HTMLParser(AbstractFormatter( \ 46 | DumbWriter(StringIO()))) 47 | self.parser.feed(open(self.file).read()) 48 | self.parser.close() 49 | return self.parse.anchorlist 50 | 51 | class Crawler(object): # manage entire crawling process 52 | 53 | count = 0 # static downloaded page counter 54 | 55 | def __init__(self, url): 56 | self.q = [url] 57 | self.seen = [] 58 | self.dom = urlparse(url)[1] 59 | 60 | def getPage(self, url): 61 | r = Retriever(url) 62 | retval = r.download() 63 | if retval[0] == '*': # error situation, do not parse 64 | print retval, '... skipping parse' 65 | return 66 | Crawler.count = Crawler.count + 1 67 | print '\n(', Crawler.count, ')' 68 | print 'URL:', url 69 | print 'FILE:', retval[0] 70 | self.seen.append(url) 71 | 72 | links = r.parseAndGetLinks() # get and process links 73 | for eachLink in links: 74 | if eachLink[:4] != 'http' and \ 75 | find(eachLink, '://') == -1: 76 | eachLink = urljoin(url, eachLink) 77 | print '* ', eachLink, 78 | 79 | if find(lower(eachLink), 'mailto:') != -1: 80 | print '... discarded, mailto link' 81 | continue 82 | 83 | if eachLink not in self.seen: 84 | if find(eachLink, self.dom) == -1: 85 | print '... discarded, not in domain' 86 | else: 87 | if eachLink not in self.q: 88 | self.q.append(eachLink) 89 | print '... new, added to Q' 90 | else: 91 | print '... discarded, already in Q' 92 | else: 93 | print '... discarded, already processed' 94 | 95 | def go(self): # process links in queue 96 | while self.q: 97 | url = self.q.pop() 98 | self.getPage(url) 99 | 100 | def main(): 101 | if len(argv) > 1: 102 | url = argv[1] 103 | else: 104 | try: 105 | url = raw_input('Enter starting URL: ') 106 | except (KeyboardInterrupt, EOFError): 107 | url = '' 108 | 109 | if not url: return 110 | robot = Crawler(url) 111 | robot.go() 112 | 113 | if __name__ == '__main__': 114 | main() 115 | -------------------------------------------------------------------------------- /ch19/alt/listdir.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id: listdir.py,v 1.8 2000/05/26 10:19:30 wesc Exp $ 3 | # 4 | # listdir.py -- traverse directory tree 5 | # 6 | # created by wesc 00/02/20 7 | # 8 | 9 | import Tkinter, os, time, string 10 | __version__ = string.split('$Revision: 1.8 $')[1] 11 | 12 | class DirList: 13 | 14 | # do everything! 15 | def __init__(self, initdir=None): 16 | self.top = Tkinter.Tk() 17 | self.label = Tkinter.Label(self.top, text='Directory Lister' + ' v' + __version__) 18 | self.label.pack() 19 | self.cwd=Tkinter.StringVar(self.top) 20 | self.dirl = Tkinter.Label(self.top, fg='blue', font=('Helvetica', 12, 'bold')) 21 | self.dirl.pack() 22 | 23 | self.dirfm = Tkinter.Frame(self.top) 24 | self.dirsb = Tkinter.Scrollbar(self.dirfm) 25 | self.dirsb.pack(side=Tkinter.RIGHT, fill=Tkinter.Y) 26 | 27 | self.dirs = Tkinter.Listbox(self.dirfm, height=15, width=50, yscrollcommand=self.dirsb.set) 28 | self.dirs.bind('', self.setdirandgo) 29 | self.dirsb.config(command=self.dirs.yview) 30 | self.dirs.pack(side=Tkinter.LEFT, fill=Tkinter.BOTH) 31 | self.dirfm.pack() 32 | 33 | self.dirn = Tkinter.Entry(self.top, width=50, textvariable=self.cwd) 34 | self.dirn.bind('', self.dols) 35 | self.dirn.pack() 36 | 37 | self.bfm = Tkinter.Frame(self.top) 38 | self.clr = Tkinter.Button(self.bfm, text='Clear', command=self.clrdir, activeforeground='white', activebackground='blue') 39 | self.ls = Tkinter.Button(self.bfm, text='List Directory', command=self.dols, activeforeground='white', activebackground='green') 40 | self.quit = Tkinter.Button(self.bfm, text='Quit', command=self.top.quit, activeforeground='white', activebackground='red') 41 | self.clr.pack(side=Tkinter.LEFT) 42 | self.ls.pack(side=Tkinter.LEFT) 43 | self.quit.pack(side=Tkinter.LEFT) 44 | self.bfm.pack() 45 | 46 | if initdir: 47 | # put selection in entry and do it 48 | self.cwd.set(os.curdir) 49 | self.dols() 50 | 51 | 52 | # clear entry 53 | def clrdir(self, ev=None): 54 | self.cwd.set('') 55 | 56 | # set dir entry 57 | def setdirandgo(self, ev=None): 58 | 59 | # save last search 60 | self.last = self.cwd.get() 61 | 62 | # set red bg while searching 63 | self.dirs.config(selectbackground='red') 64 | 65 | # grab listbox selection, default to ('.') os.curdir if not there 66 | check = self.dirs.get(self.dirs.curselection()) 67 | if not check: 68 | check = os.curdir 69 | 70 | # grab selection and strip any extra chars (a la 'ls -F') 71 | if check[-1] in '@/*': check = check[:-1] 72 | 73 | # set entry and run 74 | self.cwd.set(check) 75 | self.dols() 76 | 77 | 78 | def dols(self, ev=None): 79 | 80 | error = '' 81 | # check if a exist and if directory 82 | tdir = self.cwd.get() 83 | vi = 0 84 | if not tdir: 85 | tdir = os.curdir 86 | if not os.path.exists(tdir): 87 | error = tdir + ': no such file' 88 | elif not os.path.isdir(tdir): 89 | if os.name == 'posix': 90 | vi = 1 91 | error = tdir + ': starting "vi" in xterm...' 92 | else: 93 | error = tdir + ': not a directory' 94 | if error: 95 | self.cwd.set(error) 96 | self.top.update() 97 | time.sleep(2) 98 | if not (hasattr(self, 'last') and self.last): 99 | self.last = os.curdir 100 | self.cwd.set(self.last) 101 | self.dirs.config(selectbackground='LightSkyBlue') 102 | self.top.update() 103 | if vi: 104 | os.system("xterm -rv -e vi " + tdir) 105 | return 106 | 107 | # get listing 108 | self.cwd.set('FETCHING DIRECTORY CONTENTS...') 109 | self.top.update() 110 | dirlist = os.listdir(tdir) 111 | 112 | # go there to for relativity 113 | os.chdir(tdir) 114 | self.dirl.config(text=os.getcwd()) 115 | 116 | # replace old file listing 117 | self.dirs.delete(0, Tkinter.END) 118 | self.dirs.insert(Tkinter.END, os.curdir) 119 | self.dirs.insert(Tkinter.END, os.pardir) 120 | for eachFile in dirlist: 121 | self.dirs.insert(Tkinter.END, eachFile) 122 | self.cwd.set(tdir) 123 | self.dirs.config(selectbackground='LightSkyBlue') 124 | 125 | d = DirList(os.curdir) 126 | Tkinter.mainloop() 127 | -------------------------------------------------------------------------------- /ch10/alt/myexc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id$ 4 | 5 | myexc.py -- "my exceptions" demo which highlights user-created 6 | exceptions. NOTE: this example does not currently work with 7 | JPython as neither the errno nor tempfile modules have been 8 | implemented, and also, the socket module is incomplete. 9 | ''' 10 | 11 | # import all our needed modules 12 | import os, socket, errno, types, tempfile 13 | 14 | # create our a new NetworkError exception, derived from IOError 15 | class NetworkError(IOError): 16 | pass 17 | 18 | # create our a new FileError exception, derived from IOError 19 | class FileError(IOError): 20 | pass 21 | 22 | # updArgs --> tuple 23 | def updArgs(args, newarg=None): 24 | '''updArgs(args, newarg=None) -- if instance, grab each exception 25 | instance argument and place them in a list; otherwise, just 26 | convert given args sequence to a list for mutability; add 27 | newarg if necessary; then convert the whole thing to a tuple.''' 28 | 29 | if isinstance(args, IOError): 30 | myargs = [] 31 | myargs.extend([arg for arg in args]) 32 | else: 33 | myargs = list(args) 34 | 35 | if newarg: 36 | myargs.append(newarg) 37 | 38 | return tuple(myargs) 39 | 40 | 41 | # fileArgs --> tuple 42 | def fileArgs(fn, mode, args): 43 | '''fileArgs(fn, mode, args) -- similar to updArgs() except made 44 | specifically for files; creates small permission string and 45 | formats error to be similar to other IOError exceptions.''' 46 | 47 | if args[0] == errno.EACCES and \ 48 | 'access' in dir(os): 49 | perms = '' 50 | permd = { 'r': os.R_OK, 'w': os.W_OK, \ 51 | 'x': os.X_OK } 52 | pkeys = permd.keys() 53 | pkeys.sort() 54 | pkeys.reverse() 55 | 56 | for eachPerm in 'rwx': 57 | if os.access(fn, permd[eachPerm]): 58 | perms = perms + eachPerm 59 | else: 60 | perms = perms + '-' 61 | 62 | if isinstance(args, IOError): 63 | myargs = [] 64 | myargs.extend([arg for arg in args]) 65 | else: 66 | myargs = list(args) 67 | 68 | myargs[1] = "'%s' %s (perms: '%s')" % \ 69 | (mode, myargs[1], perms) 70 | 71 | myargs.append(args.filename) 72 | 73 | else: 74 | myargs = args 75 | 76 | return tuple(myargs) 77 | 78 | # myconnect() --> None (raises exception on error) 79 | def myconnect(sock, host, port): 80 | '''myconnect(sock, host, port) -- attempt to make a network connection 81 | with the given socket and host-port pair; raises our new NetworkError 82 | exception and collates error number and reason.''' 83 | 84 | try: 85 | sock.connect(host, port) 86 | 87 | except socket.error, args: 88 | myargs = updArgs(args) # convert inst to tuple 89 | if len(myargs) == 1: # no #s on some errors 90 | myargs = (errno.ENXIO, myargs[0]) 91 | 92 | raise NetworkError, \ 93 | updArgs(myargs, host + ':' + str(port)) 94 | 95 | 96 | # myopen() --> file object 97 | def myopen(fn, mode='r'): 98 | '''myopen(fn, mode) -- wrapper around the open() built-in function 99 | such that we raise our new FileError exception on an error situation 100 | and collate a set of FileError exception arguments to pass to the user''' 101 | 102 | try: 103 | fo = open(fn, mode) 104 | 105 | except IOError, args: 106 | raise FileError, fileArgs(fn, mode, args) 107 | 108 | return fo 109 | 110 | 111 | # testfile() --> None 112 | def testfile(): 113 | '''testfile() -- runs the file tester, setting a variety of test files 114 | which should generate FileError exceptions''' 115 | 116 | fn = tempfile.mktemp() 117 | f = open(fn, 'w') 118 | f.close() 119 | 120 | for eachTest in ((0, 'r'), (0100, 'r'), (0400, 'w'), (0500, 'w')): 121 | try: 122 | os.chmod(fn, eachTest[0]) 123 | f = myopen(fn, eachTest[1]) 124 | 125 | except FileError, args: 126 | print "%s: %s" % \ 127 | (args.__class__.__name__, args) 128 | else: 129 | print fn, "opened ok... perms ignored" 130 | f.close() 131 | 132 | os.chmod(fn, 0777) 133 | os.unlink(fn) 134 | 135 | 136 | # testnet() --> None 137 | def testnet(): 138 | '''testfile() -- runs the network tester, making various connections 139 | which should generate NetworkError exceptions''' 140 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 141 | 142 | for eachHost in (YOUR HOSTS HERE): 143 | try: 144 | myconnect(s, eachHost, 80) 145 | except NetworkError, args: 146 | print "%s: %s" % (args.__class__.__name__, args) 147 | else: 148 | print "network connection successful to", `eachHost` 149 | s.close() 150 | 151 | 152 | # run tests if invoked as a script 153 | if __name__ == '__main__': 154 | testfile() 155 | testnet() 156 | -------------------------------------------------------------------------------- /ch21/ushuffle_db.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | from random import randrange as rrange 5 | 6 | COLSIZ = 10 7 | RDBMSs = {'s': 'sqlite', 'm': 'mysql', 'g': 'gadfly'} 8 | DB_EXC = None 9 | 10 | def setup(): 11 | return RDBMSs[raw_input(''' 12 | Choose a database system: 13 | 14 | (M)ySQL 15 | (G)adfly 16 | (S)QLite 17 | 18 | Enter choice: ''').strip().lower()[0]] 19 | 20 | def connect(db, dbName): 21 | global DB_EXC 22 | dbDir = '%s_%s' % (db, dbName) 23 | 24 | if db == 'sqlite': 25 | try: 26 | import sqlite3 27 | except ImportError, e: 28 | try: 29 | from pysqlite2 import dbapi2 as sqlite3 30 | except ImportError, e: 31 | return None 32 | 33 | DB_EXC = sqlite3 34 | if not os.path.isdir(dbDir): 35 | os.mkdir(dbDir) 36 | cxn = sqlite3.connect(os.path.join(dbDir, dbName)) 37 | 38 | elif db == 'mysql': 39 | try: 40 | import MySQLdb 41 | import _mysql_exceptions as DB_EXC 42 | except ImportError, e: 43 | return None 44 | 45 | try: 46 | cxn = MySQLdb.connect(db=dbName) 47 | except DB_EXC.OperationalError, e: 48 | cxn = MySQLdb.connect(user='root') 49 | try: 50 | cxn.query('DROP DATABASE %s' % dbName) 51 | except DB_EXC.OperationalError, e: 52 | pass 53 | cxn.query('CREATE DATABASE %s' % dbName) 54 | cxn.query("GRANT ALL ON %s.* to ''@'localhost'" % dbName) 55 | cxn.commit() 56 | cxn.close() 57 | cxn = MySQLdb.connect(db=dbName) 58 | 59 | elif db == 'gadfly': 60 | try: 61 | from gadfly import gadfly 62 | DB_EXC = gadfly 63 | except ImportError, e: 64 | return None 65 | 66 | try: 67 | cxn = gadfly(dbName, dbDir) 68 | except IOError, e: 69 | cxn = gadfly() 70 | if not os.path.isdir(dbDir): 71 | os.mkdir(dbDir) 72 | cxn.startup(dbName, dbDir) 73 | else: 74 | return None 75 | return cxn 76 | 77 | def create(cur): 78 | try: 79 | cur.execute(''' 80 | CREATE TABLE users ( 81 | login VARCHAR(8), 82 | uid INTEGER, 83 | prid INTEGER) 84 | ''') 85 | except DB_EXC.OperationalError, e: 86 | drop(cur) 87 | create(cur) 88 | 89 | drop = lambda cur: cur.execute('DROP TABLE users') 90 | 91 | NAMES = ( 92 | ('aaron', 8312), ('angela', 7603), ('dave', 7306), 93 | ('davina',7902), ('elliot', 7911), ('ernie', 7410), 94 | ('jess', 7912), ('jim', 7512), ('larry', 7311), 95 | ('leslie', 7808), ('melissa', 8602), ('pat', 7711), 96 | ('serena', 7003), ('stan', 7607), ('faye', 6812), 97 | ('amy', 7209), 98 | ) 99 | 100 | def randName(): 101 | pick = list(NAMES) 102 | while len(pick) > 0: 103 | yield pick.pop(rrange(len(pick))) 104 | 105 | def insert(cur, db): 106 | if db == 'sqlite': 107 | cur.executemany("INSERT INTO users VALUES(?, ?, ?)", 108 | [(who, uid, rrange(1,5)) for who, uid in randName()]) 109 | elif db == 'gadfly': 110 | for who, uid in randName(): 111 | cur.execute("INSERT INTO users VALUES(?, ?, ?)", 112 | (who, uid, rrange(1,5))) 113 | elif db == 'mysql': 114 | cur.executemany("INSERT INTO users VALUES(%s, %s, %s)", 115 | [(who, uid, rrange(1,5)) for who, uid in randName()]) 116 | 117 | getRC = lambda cur: cur.rowcount if hasattr(cur, 'rowcount') else -1 118 | 119 | def update(cur): 120 | fr = rrange(1,5) 121 | to = rrange(1,5) 122 | cur.execute( 123 | "UPDATE users SET prid=%d WHERE prid=%d" % (to, fr)) 124 | return fr, to, getRC(cur) 125 | 126 | def delete(cur): 127 | rm = rrange(1,5) 128 | cur.execute('DELETE FROM users WHERE prid=%d' % rm) 129 | return rm, getRC(cur) 130 | 131 | def dbDump(cur): 132 | cur.execute('SELECT * FROM users') 133 | print '\n%s%s%s' % ('LOGIN'.ljust(COLSIZ), 134 | 'USERID'.ljust(COLSIZ), 'PROJ#'.ljust(COLSIZ)) 135 | for data in cur.fetchall(): 136 | print '%s%s%s' % tuple([str(s).title().ljust(COLSIZ) \ 137 | for s in data]) 138 | 139 | def main(): 140 | db = setup() 141 | print '*** Connecting to %r database' % db 142 | cxn = connect(db, 'test') 143 | if not cxn: 144 | print '\nERROR: %r not supported, exiting' % db 145 | return 146 | cur = cxn.cursor() 147 | 148 | print '\n*** Creating users table' 149 | create(cur) 150 | 151 | print '\n*** Inserting names into table' 152 | insert(cur, db) 153 | dbDump(cur) 154 | 155 | print '\n*** Randomly moving folks', 156 | fr, to, num = update(cur) 157 | print 'from one group (%d) to another (%d)' % (fr, to) 158 | print '\t(%d users moved)' % num 159 | dbDump(cur) 160 | 161 | print '\n*** Randomly choosing group', 162 | rm, num = delete(cur) 163 | print '(%d) to delete' % rm 164 | print '\t(%d users removed)' % num 165 | dbDump(cur) 166 | 167 | print '\n*** Dropping users table' 168 | drop(cur) 169 | cur.close() 170 | cxn.commit() 171 | cxn.close() 172 | 173 | if __name__ == '__main__': 174 | main() 175 | -------------------------------------------------------------------------------- /ch21/alt/ushuffle_dbPRE25.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | from random import randrange as rrange 5 | 6 | COLSIZ = 10 7 | RDBMSs = {'s': 'sqlite', 'm': 'mysql', 'g': 'gadfly'} 8 | DB_EXC = None 9 | 10 | def setup(): 11 | return RDBMSs[raw_input(''' 12 | Choose a database system: 13 | 14 | (M)ySQL 15 | (G)adfly 16 | (S)QLite 17 | 18 | Enter choice: ''').strip().lower()[0]] 19 | 20 | def connect(db, dbName): 21 | global DB_EXC 22 | dbDir = '%s_%s' % (db, dbName) 23 | 24 | if db == 'sqlite': 25 | try: 26 | import sqlite3 27 | except ImportError, e: 28 | try: 29 | from pysqlite2 import dbapi2 as sqlite3 30 | except ImportError, e: 31 | return None 32 | 33 | DB_EXC = sqlite3 34 | if not os.path.isdir(dbDir): 35 | os.mkdir(dbDir) 36 | cxn = sqlite3.connect(os.path.join(dbDir, dbName)) 37 | 38 | elif db == 'mysql': 39 | try: 40 | import MySQLdb 41 | import _mysql_exceptions as DB_EXC 42 | except ImportError, e: 43 | return None 44 | 45 | try: 46 | cxn = MySQLdb.connect(db=dbName) 47 | except DB_EXC.OperationalError, e: 48 | cxn = MySQLdb.connect(user='root') 49 | try: 50 | cxn.query('DROP DATABASE %s' % dbName) 51 | except DB_EXC.OperationalError, e: 52 | pass 53 | cxn.query('CREATE DATABASE %s' % dbName) 54 | cxn.query("GRANT ALL ON %s.* to ''@'localhost'" % dbName) 55 | cxn.commit() 56 | cxn.close() 57 | cxn = MySQLdb.connect(db=dbName) 58 | 59 | elif db == 'gadfly': 60 | try: 61 | from gadfly import gadfly 62 | DB_EXC = gadfly 63 | except ImportError, e: 64 | return None 65 | 66 | try: 67 | cxn = gadfly(dbName, dbDir) 68 | except IOError, e: 69 | cxn = gadfly() 70 | if not os.path.isdir(dbDir): 71 | os.mkdir(dbDir) 72 | cxn.startup(dbName, dbDir) 73 | else: 74 | return None 75 | return cxn 76 | 77 | def create(cur): 78 | try: 79 | cur.execute(''' 80 | CREATE TABLE users ( 81 | login VARCHAR(8), 82 | uid INTEGER, 83 | prid INTEGER) 84 | ''') 85 | except DB_EXC.OperationalError, e: 86 | drop(cur) 87 | create(cur) 88 | 89 | drop = lambda cur: cur.execute('DROP TABLE users') 90 | 91 | NAMES = ( 92 | ('aaron', 8312), ('angela', 7603), ('dave', 7306), 93 | ('davina',7902), ('elliot', 7911), ('ernie', 7410), 94 | ('jess', 7912), ('jim', 7512), ('larry', 7311), 95 | ('leslie', 7808), ('melissa', 8602), ('pat', 7711), 96 | ('serena', 7003), ('stan', 7607), ('faye', 6812), 97 | ('amy', 7209), 98 | ) 99 | 100 | def randName(): 101 | pick = list(NAMES) 102 | while len(pick) > 0: 103 | yield pick.pop(rrange(len(pick))) 104 | 105 | def insert(cur, db): 106 | if db == 'sqlite': 107 | cur.executemany("INSERT INTO users VALUES(?, ?, ?)", 108 | [(who, uid, rrange(1,5)) for who, uid in randName()]) 109 | elif db == 'gadfly': 110 | for who, uid in randName(): 111 | cur.execute("INSERT INTO users VALUES(?, ?, ?)", 112 | (who, uid, rrange(1,5))) 113 | elif db == 'mysql': 114 | cur.executemany("INSERT INTO users VALUES(%s, %s, %s)", 115 | [(who, uid, rrange(1,5)) for who, uid in randName()]) 116 | 117 | getRC = lambda cur: (hasattr(cur, 'rowcount') and [cur.rowcount] or [-1])[0] 118 | #getRC = cur.rowcount if hasattr(cur, 'rowcount') else -1 119 | 120 | def update(cur): 121 | fr = rrange(1,5) 122 | to = rrange(1,5) 123 | cur.execute( 124 | "UPDATE users SET prid=%d WHERE prid=%d" % (to, fr)) 125 | return fr, to, getRC(cur) 126 | 127 | def delete(cur): 128 | rm = rrange(1,5) 129 | cur.execute('DELETE FROM users WHERE prid=%d' % rm) 130 | return rm, getRC(cur) 131 | 132 | def dbDump(cur): 133 | cur.execute('SELECT * FROM users') 134 | print '\n%s%s%s' % ('LOGIN'.ljust(COLSIZ), 135 | 'USERID'.ljust(COLSIZ), 'PROJ#'.ljust(COLSIZ)) 136 | for data in cur.fetchall(): 137 | print '%s%s%s' % tuple([str(s).title().ljust(COLSIZ) \ 138 | for s in data]) 139 | 140 | def main(): 141 | db = setup() 142 | print '*** Connecting to %r database' % db 143 | cxn = connect(db, 'test') 144 | if not cxn: 145 | print '\nERROR: %r not supported, exiting' % db 146 | return 147 | cur = cxn.cursor() 148 | 149 | print '\n*** Creating users table' 150 | create(cur) 151 | 152 | print '\n*** Inserting names into table' 153 | insert(cur, db) 154 | dbDump(cur) 155 | 156 | print '\n*** Randomly moving folks', 157 | fr, to, num = update(cur) 158 | print 'from one group (%d) to another (%d)' % (fr, to) 159 | print '\t(%d users moved)' % num 160 | dbDump(cur) 161 | 162 | print '\n*** Randomly choosing group', 163 | rm, num = delete(cur) 164 | print '(%d) to delete' % rm 165 | print '\t(%d users removed)' % num 166 | dbDump(cur) 167 | 168 | print '\n*** Dropping users table' 169 | drop(cur) 170 | cur.close() 171 | cxn.commit() 172 | cxn.close() 173 | 174 | if __name__ == '__main__': 175 | main() 176 | -------------------------------------------------------------------------------- /ch14/alt/loopmake.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id: loopmaker.py,v 1.7 2000/04/22 01:44:26 wesc Exp $ 3 | # 4 | # loopmaker.py -- CASE script: creates Python loops given parameters 5 | # 6 | # created on 00/04/21 by wesc 7 | # 8 | 9 | from keyword import iskeyword 10 | 11 | # setup exec_str dictionary 12 | exec_dict = { 13 | 14 | # FOR loop 15 | 'f': ''' 16 | for %s in %s: 17 | print %s 18 | ''', 19 | 20 | # WHILE loop (sequences) 21 | 's': ''' 22 | %s = 0 23 | %s = %s 24 | while %s < len(%s): 25 | print %s[%s] 26 | %s = %s + 1 27 | ''', 28 | 29 | # WHILE loop (numbers) 30 | 'n': ''' 31 | %s = %d 32 | while %s < %d: 33 | print %s 34 | %s = %s + %d 35 | ''' 36 | } 37 | 38 | dashes = '\n' + ('-' * 50) 39 | def dashedprint(data, dashes=dashes): 40 | print data + dashes 41 | 42 | def main(): 43 | 44 | # prompt for loop type 45 | while 1: 46 | ltype = raw_input('Loop type? ([F]or/While) ') 47 | if not ltype: ltype = 'f' 48 | if ltype[0] in 'fw': 49 | break 50 | 51 | # prompt for data type 52 | while 1: 53 | dtype = raw_input('Data type? ([N]umber/Sequence [str,list,tuple]) ') 54 | if not dtype: dtype = 'n' 55 | if dtype[0] in 'ns': 56 | break 57 | 58 | # NUMBER type 59 | if dtype == 'n': 60 | while 1: 61 | start = raw_input('Starting value? [0] ') 62 | if not start: 63 | start = 0 64 | else: 65 | start = int(start) 66 | while 1: 67 | stop = input('Ending value (non-inclusive)? ') 68 | if type(stop) != type(0): 69 | print '*** Ending value must be an integer\n' 70 | else: 71 | break 72 | step = raw_input('Stepping value? [1] ') 73 | if not step: 74 | step = 1 75 | else: 76 | step = int(step) 77 | seq = str(range(start, stop, step)) 78 | if seq == '[]': 79 | ans = raw_input('*** Invalid range; change your values? ([y]/n) ') 80 | if not ans or ans[0] == 'y': 81 | continue 82 | print 83 | break 84 | 85 | # SEQUENCE type 86 | else: 87 | while 1: 88 | seq = raw_input('Enter sequence (string, list, or tuple): ') 89 | 90 | try: 91 | test = eval(seq) 92 | 93 | # invalid sequence... reprompt 94 | except SyntaxError: 95 | # keyword can be a string 96 | if iskeyword(seq): 97 | test = seq = `seq` 98 | else: 99 | print "*** Invalid Python sequence data '%s'\n" % seq 100 | continue 101 | 102 | # user typed in string without the quotes... add the quotes using repr() 103 | except NameError: 104 | test = seq = `seq` 105 | 106 | # must be string, list, or tuple 107 | if type(test) != type('') and type(test) != type([]) and type(test) != type(()): 108 | print "*** Invalid Python sequence data '%s'\n" % seq 109 | continue 110 | 111 | break 112 | 113 | # iterator variable 114 | while 1: 115 | var = raw_input('Enter iterative variable name? ') 116 | if not var: 117 | print '*** Identifier name is required!\n' 118 | elif iskeyword(var) or var in dir(__builtins__): 119 | print "*** Identifier '%s' name is a keyword or built-in!\n" % var 120 | else: 121 | try: 122 | exec var + '=0' 123 | except SyntaxError: 124 | print "*** Invalid identifier '%s'!\n" % var 125 | continue 126 | break 127 | 128 | # FOR loop 129 | if ltype == 'f': 130 | exec_str = exec_dict['f'] % (var, seq, var) 131 | 132 | # WHILE loop 133 | elif ltype == 'w': 134 | 135 | # sequence length variable (only for sequences) 136 | if dtype == 's': 137 | while 1: 138 | svar = raw_input('Enter sequence name? ') 139 | if not svar: 140 | print '*** Identifier name is required for while loops!\n' 141 | elif iskeyword(svar) or svar in dir(__builtins__): 142 | print "*** Identifier '%s' name is a keyword or built-in!\n" % svar 143 | else: 144 | break 145 | else: 146 | svar = None 147 | 148 | # must assign to sequence var if using sequences 149 | if dtype == 's': 150 | exec_str = exec_dict['s'] % (var, svar, seq, var, svar, svar, var, var, var) 151 | 152 | # use range() values for loop if using numbers 153 | elif dtype == 'n': 154 | exec_str = exec_dict['n'] % (var, start, var, stop, var, var, var, step) 155 | 156 | # EXECUTE code 157 | dashedprint('') 158 | dashedprint('The custom-generated code for you is:') 159 | dashedprint(exec_str) 160 | dashedprint('Test execution of the code:') 161 | exec exec_str 162 | dashedprint('') 163 | 164 | 165 | # top-level executes main() 166 | if __name__ == '__main__': 167 | print 'Welcome to Loop Maker v1.0\n' 168 | 169 | while 1: 170 | main() 171 | try: 172 | again = raw_input('Try again? ([Y]es/No) ') 173 | except: 174 | print 175 | break 176 | if again and again[0] != 'y': 177 | break 178 | -------------------------------------------------------------------------------- /ch20/advcgi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from cgi import FieldStorage 4 | from os import environ 5 | from cStringIO import StringIO 6 | from urllib import quote, unquote 7 | from string import capwords, strip, split, join 8 | 9 | class AdvCGI: 10 | 11 | header = 'Content-Type: text/html\n\n' 12 | url = '/py/advcgi.py' 13 | 14 | formhtml = ''' 15 | Advanced CGI Demo 16 |

Advanced CGI Demo Form

17 |
18 |

My Cookie Setting

19 |
  • CPPuser = %s 20 |

    Enter cookie value
    21 | (optional)

    22 |

    Enter your name
    23 | (required)

    24 |

    What languages can you program in? 25 | (at least one required)

    26 | %s 27 |

    Enter file to upload

    28 | 29 |

    30 |

  • ''' 31 | 32 | langSet = ('Python', 'PERL', 'Java', 'C++', 'PHP', 33 | 'C', 'JavaScript') 34 | langItem = \ 35 | ' %s\n' 36 | 37 | def getCPPCookies(self): # reads cookies from client 38 | if environ.has_key('HTTP_COOKIE'): 39 | for eachCookie in map(strip, \ 40 | split(environ['HTTP_COOKIE'], ';')): 41 | if len(eachCookie) > 6 and \ 42 | eachCookie[:3] == 'CPP': 43 | tag = eachCookie[3:7] 44 | try: 45 | self.cookies[tag] = \ 46 | eval(unquote(eachCookie[8:])) 47 | except (NameError, SyntaxError): 48 | self.cookies[tag] = \ 49 | unquote(eachCookie[8:]) 50 | else: 51 | self.cookies['info'] = self.cookies['user'] = '' 52 | 53 | if self.cookies['info'] != '': 54 | self.who, langStr, self.fn = \ 55 | split(self.cookies['info'], ':') 56 | self.langs = split(langStr, ',') 57 | else: 58 | self.who = self.fn = '' 59 | self.langs = ['Python'] 60 | 61 | def showForm(self): # show fill-out form 62 | self.getCPPCookies() 63 | langStr = '' 64 | for eachLang in AdvCGI.langSet: 65 | if eachLang in self.langs: 66 | langStr = langStr + AdvCGI.langItem % \ 67 | (eachLang, ' CHECKED', eachLang) 68 | else: 69 | langStr = langStr + AdvCGI.langItem % \ 70 | (eachLang, '', eachLang) 71 | 72 | if not self.cookies.has_key('user') or \ 73 | self.cookies['user'] == '': 74 | cookieStatus = '(cookie has not been set yet)' 75 | userCook = '' 76 | else: 77 | userCook = cookieStatus = self.cookies['user'] 78 | 79 | print AdvCGI.header + AdvCGI.formhtml % (AdvCGI.url, 80 | cookieStatus, userCook, self.who, langStr, self.fn) 81 | 82 | errhtml = ''' 83 | Advanced CGI Demo 84 |

    ERROR

    85 | %s

    86 |

    88 | ''' 89 | 90 | def showError(self): 91 | print AdvCGI.header + AdvCGI.errhtml % (self.error) 92 | 93 | reshtml = ''' 94 | Advanced CGI Demo 95 |

    Your Uploaded Data

    96 |

    Your cookie value is: %s

    97 |

    Your name is: %s

    98 |

    You can program in the following languages:

    99 | 100 |

    Your uploaded file...
    101 | Name: %s
    102 | Contents:

    103 |
    %s
    104 | Click here to return to form. 105 | ''' 106 | 107 | def setCPPCookies(self): 108 | for eachCookie in self.cookies.keys(): 109 | print 'Set-Cookie: CPP%s=%s; path=/' % \ 110 | (eachCookie, quote(self.cookies[eachCookie])) 111 | 112 | def doResults(self): 113 | MAXBYTES = 1024 114 | langlist = '' 115 | for eachLang in self.langs: 116 | langlist = langlist + '
  • %s
    ' % eachLang 117 | 118 | filedata = '' 119 | while len(filedata) < MAXBYTES: # read file chunks 120 | data = self.fp.readline() 121 | if data == '': break 122 | filedata = filedata + data 123 | else: # truncate if too long 124 | filedata = filedata + \ 125 | '... (file truncated due to size)' 126 | self.fp.close() 127 | if filedata == '': 128 | filedata = \ 129 | '(file upload error or file not given)' 130 | filename = self.fn 131 | 132 | if not self.cookies.has_key('user') or \ 133 | self.cookies['user'] == '': 134 | cookieStatus = '(cookie has not been set yet)' 135 | userCook = '' 136 | else: 137 | userCook = cookieStatus = self.cookies['user'] 138 | 139 | self.cookies['info'] = join([self.who, \ 140 | join(self.langs, ','), filename], ':') 141 | self.setCPPCookies() 142 | print AdvCGI.header + AdvCGI.reshtml % \ 143 | (cookieStatus, self.who, langlist, 144 | filename, filedata, AdvCGI.url) 145 | 146 | def go(self): # determine which page to return 147 | self.cookies = {} 148 | self.error = '' 149 | form = FieldStorage() 150 | if form.keys() == []: 151 | self.showForm() 152 | return 153 | 154 | if form.has_key('person'): 155 | self.who = capwords(strip(form['person'].value)) 156 | if self.who == '': 157 | self.error = 'Your name is required. (blank)' 158 | else: 159 | self.error = 'Your name is required. (missing)' 160 | 161 | if form.has_key('cookie'): 162 | self.cookies['user'] = unquote(strip( \ 163 | form['cookie'].value)) 164 | else: 165 | self.cookies['user'] = '' 166 | 167 | self.langs = [] 168 | if form.has_key('lang'): 169 | langdata = form['lang'] 170 | if type(langdata) == type([]): 171 | for eachLang in langdata: 172 | self.langs.append(eachLang.value) 173 | else: 174 | self.langs.append(langdata.value) 175 | else: 176 | self.error = 'At least one language required.' 177 | 178 | if form.has_key('upfile'): 179 | upfile = form["upfile"] 180 | self.fn = upfile.filename or '' 181 | if upfile.file: 182 | self.fp = upfile.file 183 | else: 184 | self.fp = StringIO('(no data)') 185 | else: 186 | self.fp = StringIO('(no file)') 187 | self.fn = '' 188 | 189 | if not self.error: 190 | self.doResults() 191 | else: 192 | self.showError() 193 | 194 | if __name__ == '__main__': 195 | page = AdvCGI() 196 | page.go() 197 | -------------------------------------------------------------------------------- /ch20/alt/advcgi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id: advcgi.py,v 1.1 2000/12/31 01:32:45 wesc Exp $ 4 | 5 | advcgi.py -- tests CGI file uploads and multi-valued CGI variables 6 | 7 | Advanced CGI demo 8 | 9 | created by wesc on 00/07/25 10 | ''' 11 | 12 | from cgi import FieldStorage 13 | from os import environ 14 | from StringIO import StringIO 15 | from urllib import quote, unquote 16 | from string import capwords, strip, split, join 17 | #from sys import stderr 18 | #s = stderr.write 19 | 20 | class AdvCGI: 21 | 22 | header = 'Content-Type: text/html\n\n' 23 | url = '/py/advcgi.py' 24 | 25 | formhtml = ''' 26 | Advanced CGI Demo 27 |

    Advanced CGI Demo Form

    28 |
    29 |

    My Cookie Setting

    30 |
  • CPPuser = %s 31 |

    Enter cookie value
    32 | (optional)

    33 |

    Enter your name
    34 | (required)

    35 |

    What languages can you program in? 36 | (at least one required)

    37 | %s 38 |

    Enter file to upload

    39 | 40 |

    41 |

  • ''' 42 | 43 | langSet = ('Python', 'PERL', 'Java', 'C++', 'PHP', 'C', 'JavaScript') 44 | langItem = ' %s\n' 45 | 46 | 47 | # reads cookies from client, creates cookies, who, langs 48 | def getCPPCookies(self): 49 | if environ.has_key('HTTP_COOKIE'): 50 | #s('reading cookies from server...\n') 51 | for eachCookie in map(strip, split(environ['HTTP_COOKIE'], ';')): 52 | if len(eachCookie) > 6 and eachCookie[:3] == 'CPP': 53 | tag = eachCookie[3:7] 54 | try: 55 | self.cookies[tag] = eval(unquote(eachCookie[8:])) 56 | except (NameError, SyntaxError): 57 | self.cookies[tag] = unquote(eachCookie[8:]) 58 | else: 59 | #s('no cookies on server...\n') 60 | self.cookies['info'] = self.cookies['user'] = '' 61 | 62 | #s('cookies: %s\n' % str(self.cookies)) 63 | if self.cookies['info'] != '': 64 | self.who, langStr, self.fn = split(self.cookies['info'], ':') 65 | self.langs = split(langStr, ',') 66 | else: 67 | self.who = self.fn = '' 68 | self.langs = ['Python'] 69 | 70 | 71 | def showForm(self): 72 | self.getCPPCookies() # get cookies 73 | 74 | # put together lang checkboxes 75 | langStr = '' 76 | for eachLang in AdvCGI.langSet: 77 | if eachLang in self.langs: 78 | langStr = langStr + AdvCGI.langItem % (eachLang, ' CHECKED', eachLang) 79 | else: 80 | langStr = langStr + AdvCGI.langItem % (eachLang, '', eachLang) 81 | 82 | # see if user cookie set up yet 83 | if not self.cookies.has_key('user') or self.cookies['user'] == '': 84 | cookieStatus = '(cookie has not been set yet)' 85 | userCook = '' 86 | else: 87 | userCook = cookieStatus = self.cookies['user'] 88 | 89 | # output results 90 | #s('filename: ' + self.fn + '\n') 91 | print AdvCGI.header + AdvCGI.formhtml % (AdvCGI.url, cookieStatus, userCook, self.who, langStr, self.fn) 92 | #print AdvCGI.header + AdvCGI.formhtml % (AdvCGI.url, cookieStatus, userCook, self.who, langStr) 93 | 94 | 95 | errhtml = ''' 96 | Advanced CGI Demo 97 |

    ERROR

    98 | %s

    99 |

    101 | ''' 102 | 103 | 104 | def showError(self): 105 | print AdvCGI.header + AdvCGI.errhtml % (self.error) 106 | 107 | 108 | reshtml = ''' 109 | Advanced CGI Demo 110 |

    Your Uploaded Data

    111 |

    Your cookie value is: %s

    112 |

    Your name is: %s

    113 |

    You can program in the following languages:

    114 | 115 |

    Your uploaded file...
    116 | Name: %s
    117 | Contents:

    118 |
    %s
    119 | Click here to return to form. 120 | ''' 121 | 122 | 123 | def setCPPCookies(self): 124 | for eachCookie in self.cookies.keys(): 125 | #s('setting %s cookie...\n' % eachCookie) 126 | print 'Set-Cookie: CPP%s=%s; path=/' % (eachCookie, quote(self.cookies[eachCookie])) 127 | 128 | 129 | def doResults(self): 130 | MAXBYTES = 1024 131 | langlist = '' 132 | for eachLang in self.langs: 133 | langlist = langlist + '
  • %s
    ' % eachLang 134 | filedata = '' 135 | while len(filedata) < MAXBYTES: 136 | data = self.fp.readline() 137 | if data == '': break 138 | filedata = filedata + data 139 | else: 140 | filedata = filedata + '... (file truncated due to size)' 141 | self.fp.close() 142 | if filedata == '': 143 | filedata = '(file upload error or file not given)' 144 | filename = self.fn 145 | 146 | # see if user cookie set up yet 147 | if not self.cookies.has_key('user') or self.cookies['user'] == '': 148 | cookieStatus = '(cookie has not been set yet)' 149 | userCook = '' 150 | else: 151 | userCook = cookieStatus = self.cookies['user'] 152 | 153 | # set cookies 154 | self.cookies['info'] = join([self.who, join(self.langs, ','), filename], ':') 155 | self.setCPPCookies() 156 | 157 | # output page 158 | print AdvCGI.header + AdvCGI.reshtml % (cookieStatus, self.who, langlist, filename, filedata, AdvCGI.url) 159 | 160 | 161 | def __init__(self): 162 | self.cookies = {} 163 | 164 | 165 | def go(self): 166 | self.error = '' 167 | 168 | form = FieldStorage() 169 | 170 | if form.keys() == []: 171 | #s('calling showForm()\n') 172 | self.showForm() 173 | return 174 | 175 | if form.has_key('person'): 176 | self.who = capwords(strip(form['person'].value)) 177 | if self.who == '': 178 | self.error = 'Your name is required. (blank)' 179 | else: 180 | self.error = 'Your name is required. (missing)' 181 | 182 | if form.has_key('cookie'): 183 | self.cookies['user'] = unquote(strip(form['cookie'].value)) 184 | else: 185 | self.cookies['user'] = '' 186 | 187 | self.langs = [] 188 | if form.has_key('lang'): 189 | langdata = form['lang'] 190 | if type(langdata) == type([]): 191 | for eachLang in langdata: 192 | self.langs.append(eachLang.value) 193 | else: 194 | self.langs.append(langdata.value) 195 | else: 196 | self.error = 'At least one language required.' 197 | 198 | if form.has_key('upfile'): 199 | upfile = form["upfile"] 200 | self.fn = upfile.filename or '' 201 | #s('filename is %s??\n' % self.fn) 202 | if upfile.file: 203 | self.fp = upfile.file 204 | else: 205 | self.fp = StringIO('(no data)') 206 | else: 207 | self.fp = StringIO('(no file)') 208 | self.fn = '' 209 | 210 | if not self.error: 211 | #s('calling doResults()\n') 212 | self.doResults() 213 | else: 214 | #s('calling showError()\n') 215 | self.showError() 216 | 217 | 218 | if __name__ == '__main__': 219 | page = AdvCGI() 220 | page.go() 221 | -------------------------------------------------------------------------------- /ch20/alt/advcgi2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | $Id: advcgi.py,v 1.1 2000/12/31 01:32:45 wesc Exp $ 4 | 5 | advcgi.py -- tests CGI file uploads and multi-valued CGI variables 6 | 7 | Advanced CGI demo 8 | 9 | created by wesc on 00/07/25 10 | ''' 11 | 12 | from cgi import FieldStorage 13 | from os import environ 14 | from StringIO import StringIO 15 | from urllib import quote, unquote 16 | #from sys import stderr 17 | #s = stderr.write 18 | 19 | class AdvCGI(object): 20 | 21 | header = 'Content-Type: text/html\n\n' 22 | url = '/py/advcgi.py' 23 | 24 | formhtml = ''' 25 | Advanced CGI Demo 26 |

    Advanced CGI Demo Form

    27 |
    28 |

    My Cookie Setting

    29 |
  • CPPuser = %s 30 |

    Enter cookie value
    31 | (optional)

    32 |

    Enter your name
    33 | (required)

    34 |

    What languages can you program in? 35 | (at least one required)

    36 | %s 37 |

    Enter file to upload

    38 | 39 |

    40 |

  • ''' 41 | 42 | langSet = ('Python', 'PERL', 'Java', 'C++', 'PHP', 'C', 'JavaScript') 43 | langItem = ' %s\n' 44 | 45 | 46 | # reads cookies from client, creates cookies, who, langs 47 | def getCPPCookies(self): 48 | if environ.has_key('HTTP_COOKIE'): 49 | #s('reading cookies from server...\n') 50 | #for eachCookie in map(strip, split(environ['HTTP_COOKIE'], ';')): 51 | cookies = [x.strip() for x in environ['HTTP_COOKIE'].split(';')] 52 | for eachCookie in cookies: 53 | if len(eachCookie) > 6 and eachCookie[:3] == 'CPP': 54 | tag = eachCookie[3:7] 55 | try: 56 | self.cookies[tag] = eval(unquote(eachCookie[8:])) 57 | except (NameError, SyntaxError): 58 | self.cookies[tag] = unquote(eachCookie[8:]) 59 | if not self.cookies.has_key('info'): 60 | self.cookies['info'] = '' 61 | if not self.cookies.has_key('user'): 62 | self.cookies['user'] = '' 63 | else: 64 | #s('no cookies on server...\n') 65 | self.cookies['info'] = self.cookies['user'] = '' 66 | 67 | #s('cookies: %s\n' % str(self.cookies)) 68 | if self.cookies['info'] != '': 69 | self.who, langStr, self.fn = self.cookies['info'].split(':') 70 | self.langs = langStr.split(',') 71 | else: 72 | self.who = self.fn = '' 73 | self.langs = ['Python'] 74 | 75 | 76 | def showForm(self): 77 | self.getCPPCookies() # get cookies 78 | 79 | # put together lang checkboxes 80 | langStr = '' 81 | for eachLang in AdvCGI.langSet: 82 | if eachLang in self.langs: 83 | langStr = langStr + AdvCGI.langItem % (eachLang, ' CHECKED', eachLang) 84 | else: 85 | langStr = langStr + AdvCGI.langItem % (eachLang, '', eachLang) 86 | 87 | # see if user cookie set up yet 88 | if not self.cookies.has_key('user') or self.cookies['user'] == '': 89 | cookieStatus = '(cookie has not been set yet)' 90 | userCook = '' 91 | else: 92 | userCook = cookieStatus = self.cookies['user'] 93 | 94 | # output results 95 | #s('filename: ' + self.fn + '\n') 96 | print AdvCGI.header + AdvCGI.formhtml % (AdvCGI.url, cookieStatus, userCook, self.who, langStr, self.fn) 97 | #print AdvCGI.header + AdvCGI.formhtml % (AdvCGI.url, cookieStatus, userCook, self.who, langStr) 98 | 99 | 100 | errhtml = ''' 101 | Advanced CGI Demo 102 |

    ERROR

    103 | %s

    104 |

    106 | ''' 107 | 108 | 109 | def showError(self): 110 | print AdvCGI.header + AdvCGI.errhtml % (self.error) 111 | 112 | 113 | reshtml = ''' 114 | Advanced CGI Demo 115 |

    Your Uploaded Data

    116 |

    Your cookie value is: %s

    117 |

    Your name is: %s

    118 |

    You can program in the following languages:

    119 | 120 |

    Your uploaded file...
    121 | Name: %s
    122 | Contents:

    123 |
    %s
    124 | Click here to return to form. 125 | ''' 126 | 127 | 128 | def setCPPCookies(self): 129 | for eachCookie in self.cookies.keys(): 130 | #s('setting %s cookie...\n' % eachCookie) 131 | print 'Set-Cookie: CPP%s=%s; path=/' % (eachCookie, quote(self.cookies[eachCookie])) 132 | 133 | 134 | def doResults(self): 135 | MAXBYTES = 1024 136 | langlist = '' 137 | for eachLang in self.langs: 138 | langlist = langlist + '
  • %s
    ' % eachLang 139 | filedata = '' 140 | while len(filedata) < MAXBYTES: 141 | data = self.fp.readline() 142 | if data == '': break 143 | filedata = filedata + data 144 | else: 145 | filedata = filedata + '... (file truncated due to size)' 146 | self.fp.close() 147 | if filedata == '': 148 | filedata = '(file upload error or file not given)' 149 | filename = self.fn 150 | 151 | # see if user cookie set up yet 152 | if not self.cookies.has_key('user') or self.cookies['user'] == '': 153 | cookieStatus = '(cookie has not been set yet)' 154 | userCook = '' 155 | else: 156 | userCook = cookieStatus = self.cookies['user'] 157 | 158 | # set cookies 159 | self.cookies['info'] = ':'.join([self.who, ','.join(self.langs), filename]) 160 | self.setCPPCookies() 161 | 162 | # output page 163 | print AdvCGI.header + AdvCGI.reshtml % (cookieStatus, self.who, langlist, filename, filedata, AdvCGI.url) 164 | 165 | 166 | def __init__(self): 167 | self.cookies = {} 168 | 169 | 170 | def go(self): 171 | self.error = '' 172 | 173 | form = FieldStorage() 174 | 175 | if form.keys() == []: 176 | #s('calling showForm()\n') 177 | self.showForm() 178 | return 179 | 180 | if form.has_key('person'): 181 | self.who = form['person'].value.strip().title() 182 | if self.who == '': 183 | self.error = 'Your name is required. (blank)' 184 | else: 185 | self.error = 'Your name is required. (missing)' 186 | 187 | if form.has_key('cookie'): 188 | self.cookies['user'] = unquote(form['cookie'].value.strip()) 189 | else: 190 | self.cookies['user'] = '' 191 | 192 | self.langs = [] 193 | if form.has_key('lang'): 194 | langdata = form['lang'] 195 | if type(langdata) == type([]): 196 | for eachLang in langdata: 197 | self.langs.append(eachLang.value) 198 | else: 199 | self.langs.append(langdata.value) 200 | else: 201 | self.error = 'At least one language required.' 202 | 203 | if form.has_key('upfile'): 204 | upfile = form["upfile"] 205 | self.fn = upfile.filename or '' 206 | #s('filename is %s??\n' % self.fn) 207 | if upfile.file: 208 | self.fp = upfile.file 209 | else: 210 | self.fp = StringIO('(no data)') 211 | else: 212 | self.fp = StringIO('(no file)') 213 | self.fn = '' 214 | 215 | if not self.error: 216 | #s('calling doResults()\n') 217 | self.doResults() 218 | else: 219 | #s('calling showError()\n') 220 | self.showError() 221 | 222 | 223 | if __name__ == '__main__': 224 | page = AdvCGI() 225 | page.go() 226 | --------------------------------------------------------------------------------