*** Strona 283-286 ***************************************************************

# plik feedback.py (CGI)

#!/usr/bin/python
import cgi, os, sys, string

def gush(data):
    print "Content-type: text/html\n"
    print "<h3>Thanks, %(name)s!</h3>" % vars(data)
    print "Our customer's comments are always appreciated."
    print "They drive our business directions, as well as"
    print "help us with our karma."
    print "<p>Thanks again for the feedback!<p>"
    print "And feel free to enter more comments if you wish."
    print "<p>"+10*"&nbsp;"+"--Joe."

def whimper(data):
    print "Content-type: text/html\n"
    print "<h3>Sorry, %(name)s!</h3>" % vars(data)
    print "We're very sorry to read that you had a complaint"
    print "regarding our product__We'll read your comments"
    print "carefully and will be in touch with you."
    print "<p>Nevertheless, thanks for the feedback.<p>"
    print "<p>"+10*"&nbsp;"+"--Joe."

def bail():
    print "<H3>Error filling out form</H3>"
    print "Please fill in all the fields in the form.<P>"
    print '<a href="http://localhost/comment.html">'
    print 'Go back to the form</a>'
    sys.exit()

class FormData:
    """ A repository for information gleaned from a CGI form """
    def __init__(self, formdict):
        for fieldname in self.fieldnames:
            if not form.has_key(fieldname) or form[fieldname].value == "":
                bail()
            else:
                setattr(self, fieldname, form[fieldname].value)

class FeedbackData(FormData):
    """ A FormData generated by the comment.html form. """
    fieldnames = ('name', 'address', 'email', 'type', 'text')
    def __repr__(self):
        return "%(type)s from %(name)s on %(time)s" % vars(self)

DIRECTORY = r'C:\complaintdir'

if __name__ == '__main__':
    sys.stderr = sys.stdout
    form = cgi.FieldStorage()
    data = FeedbackData(form)
    if data.type == 'comment':
        gush(data)
    else:
        whimper(data)

    # zapisujemy dane do pliku
    import tempfile, pickle, time
    tempfile.tempdir = DIRECTORY
    data.time = time.asctime(time.localtime(time.time()))
    pickle.dump(data, open(tempfile.mktemp(), 'w'))


# fragment kodu HTML

<FORM METHOD=POST ACTION="http://toftoot.com/cgi-bin/feedback.py">
<UL><I>Please fill out the entire form:</I></UL>
<CENTER><TABLE WIDTH="100%" >
<TR><TD ALIGN=RIGHT WIDTH="20%">Name:</TD>
    <TD><INPUT TYPE=text NAME=name SIZE=50 VALUE=""></TD></TR>
<TR><TD ALIGN=RIGHT>Email Address:</TD>
    <TD><INPUT TYPE=text NAME=email SIZE=50 VALUE=""></TD></TR>
<TR><TD ALIGN=RIGHT>Mailing Address:</TD>
    <TD><INPUT TYPE=text NAME=address SIZE=50 VALUE=""></TD></TR>
<TR><TD ALIGN=RIGHT>Type of Message:</TD>
<TD><INPUT TYPE=radio NAME=type CHECKED VALUE=comment>comment&nbsp;
    <INPUT TYPE=radio NAME=type VALUE=complaint>complaint</TD></TR>
<TR><TD ALIGN=RIGHT VALIGN=TOP>Enter the text in here:</TD>
    <TD><TEXTAREA NAME=text ROWS=5, COLS=50 VALUE="">
        </TEXTAREA></TD></TR>
<TR><TD></TD>
<TD><INPUT type=submit name=send value="Send the feedback!"></TD></TR>
</TABLE></CENTER>
</FORM>


# fragment kodu

form = cgi.FieldStorage()
form_ok = 1
if not form.has_key("name") or form["name"].value == "":
    form_ok = 0
else:
    data_name = form["name"].value
if not form.has_key("email") or form["email"].value == "":
    form_ok = 0
else:
    data_email = form["email"].value
...


*** Strona 288-292 ***************************************************************

# plik formletter.py (COM)

from win32com.client import constants, Dispatch
WORD = 'Word.Application.8'
False, True = 0, -1
import string

class Word:
    def __init__(self):
        self.app = Dispatch(WORD)
    def open(self, doc):
        self.app.Documents.Open(FileName=doc)
    def replace(self, source, target):
        self.app.Selection.HomeKey(Unit=constants.wdLine) 
        find = self.app.Selection.Find
        find.Text = "%"+source+"%"
        self.app.Selection.Find.Execute()
        self.app.Selection.TypeText(Text=target)
    def printdoc(self):
        self.app.Application.PrintOut()
    def close(self):
        self.app.ActiveDocument.Close(SaveChanges=False)

def print_formletter(data):
    word.open(r"h:\David\Book\tofutemplate.doc")
    word.replace("name", data.name)
    word.replace("address", data.address)
    word.replace("firstname", string.split(data.name)[0])
    word.printdoc()
    word.close()

if __name__ == '__main__':
    import os, pickle
    from feedback import DIRECTORY, FormData, FeedbackData
    word = Word()
    for filename in os.listdir(DIRECTORY):
        data = pickle.load(open(os.path.join(DIRECTORY, filename)))
        if data.type == 'complaint':
            print "Printing letter for %(name)s." % vars(data)
            print_formletter(data)
        else:
            print "Got comment from %(name)s, skipping printing." % vars(data)


# uruchomienie programu

C:\Programs> python formletter.py
Printing letter for John Doe.
Got comment from Your Mom, skipping printing.
Printing letter for Susan B. Anthony.


*** Strona 298 *******************************************************************

# plik feedbackeditor.py (Tkinter)

from FormEditor import FormEditor
from feedback import FeedbackData, FormData
from Tkinter import mainloop
FormEditor("Feedback Editor", FeedbackData, r"c:\Complaintdir")
mainloop()


# plik FormEditor.py

from Tkinter import *
import string, os, pickle

class FormEditor:
    def __init__(self, name, dataclass, storagedir):
        self.storagedir = storagedir      # schowanie niektrych odwoa
        self.dataclass = dataclass
        self.row = 0
        self.current = None

        self.root = root = Tk()           # tworzy okno i ustala jego rozmiar
        root.minsize(300,200)

        root.rowconfigure(0, weight=1)    # definiuje skal kolumny i wierszy
        root.columnconfigure(0, weight=1) # gdy zajdzie zmiana rozmiarw okna
        root.columnconfigure(1, wieght=2)
        
        # tworzenie tytuowej etykiety
        Label(root, text=name, font='bold').grid(columnspan=2)
        self.row = self.row + 1
        
        # tworzenie gwnego okna listy i jego konfiguracja
        self.listbox = Listbox(root, selectmode=SINGLE)
        self.listbox.grid(columnspan=2, sticky=E+W+N+S)
        self.listbox.bind('<ButtonRelease-1>', self.select)
        self.row = self.row + 1

        # wywouje self.add_variable dla kadej zmiennej w var nazw pl klasy 
        for fieldname in dataclass.fieldnames:
            setattr(self, fieldname, self.add_variable(root, fieldname))
  
        # tworzy zestaw przyciskw z dowizanymi poleceniami
        self.add_button(self.root, self.row, 0, 'Delete Entry', self.delentry)
        self.add_button(self.root, self.row, 1, 'Reload', self.load_data)

        self.load_data()

    def add_variable(self, root, varname): 
        Label(root, text=varname).grid(row=self.row, column=0, sticky=E)
        value = Label(root, text='', background='gray90',
                      relief=SUNKEN, anchor=W, justify=LEFT)
        value.grid(row=self.row, column=1, sticky=E+W)
        self.row = self.row + 1
        return value

    def add_button(self, root, row, column, text, command):
        button = Button(root, text=text, command=command)
        button.grid(row=row, column=column, sticky=E+W, padx=5, pady=5)

    def load_data(self):
        self.listbox.delete(0,END)
        self.items = []
        for filename in os.listdir(self.storagedir):
            item = pickle.load(open(os.path.join(self.storagedir, filename)))
            item._filename = filename
            self.items.append(item)
            self.listbox.insert('end', `item`)
        self.listbox.select_set(0)
        self.select(None)

    def select(self, event):
        selection = self.listbox.curselection()
        self.selection = self.items[int(selection[0])]
        for fieldname in self.dataclass.fieldnames:
            label = getattr(self, fieldname)               # pole GUI
            labelstr = getattr(self.selection, fieldname)  # atrybut egzemplarza
            labelstr = string.replace(labelstr, '\r','')
            label.config(text=labelstr)

    def delentry(self):
        os.remove(os.path.join(self.storagedir,self.selection._filename))
        self.load_data()


*** Strona 299-300 ***************************************************************

~/book> jpython
JPython 1.0.3 on java1.2beta4
Copyright 1997-1998 Corporation for National Research Initiatives
>>> 2 + 3
5


# plik jpythondemo.py

from pawt import swing
import java

def exit(e): java.lang.System.exit(0)

frame = swing.JFrame('Swing Example', visible=1)
button = swing.JButton('This is a Swinging example!', actionPerformed=exit)
frame.contentPane.add(button)
frame.pack()


*** Strona 301-305 ***************************************************************

# plik grapher.py (JPython)
# uwaga: poniszy kod wymaga JPythona obsugujcego modu struct
# ktry jest uywany przez modu pickle

from pawt import swing, awt, colors, GridBag
RIGHT = swing.JLabel.RIGHT
APPROVE_OPTION = swing.JFileChooser.APPROVE_OPTION
import java.io
import pickle, os

default_setup = """from math import *
def squarewave(x, order):
    total = 0.0
    for i in range(1, order*2+1, 2):
        total = total + sin(x*i/10.0)/(float(i))
    return total
"""
default_expression = "squarewave(x, order=3)"

class Chart(awt.Canvas):
    color = colors.darkturquoise
    style = 'Filled'

    def getPreferredSize(self):
        return awt.Dimension(600,300)

    def paint(self, graphics):
        clip = self.bounds
        graphics.color = colors.white
        graphics.fillRect(0, 0, clip.width, clip.height)

        width = int(clip.width * .8)
        height = int(clip.height * .8)
        x_offset = int(clip.width * .1)
        y_offset = clip.height - int(clip.height * .1)

        N = len(self.data); xs = [0]*N; ys = [0]*N

        xmin, xmax = 0, N-1
        ymax = max(self.data)
        ymin = min(self.data)

        zero_y = y_offset - int(-ymin/(ymax-ymin)*height)
        zero_x = x_offset + int(-xmin/ (xmax-xmin)*width)

        for i in range(N):
            xs[i] = int(float(i)*width/N) + x_offset
            ys[i] = y_offset - int((self.data[i]-ymin)/(ymax-ymin)*height)
        graphics.color = self.color
        if self.style == "Line":
            graphics.drawPolyline(xs, ys, len(xs))
        else:
            xs.insert(0, xs[0]); ys.insert(0, zero_y)
            xs.append(xs[-1]); ys.append(zero_y)
            graphics.fillPolygon(xs, ys, len(xs))

        # rysowanie osi
        graphics.color = colors.black
        graphics.drawLine(x_offset, zero_y, x_offset+width, zero_y)
        graphics.drawLine(zero_x, y_offset, zero_x, y_offset-height)

        # rysowanie etykiet
        leading = graphics.font.size
        graphics.drawString("%.3f" % xmin, x_offset, zero_y+leading)
        graphics.drawString("%.3f" % xmax, x_offset+width, zero_y+leading)
        graphics.drawString("%.3f" % ymin, zero_x-50, y_offset)
        graphics.drawString("%.3f" % ymax, zero_x-50, y_offset-height+leading)

class GUI:
    def __init__(self):
        self.numelements = 100
        self.frame = swing.JFrame(windowClosing=self.do_quit)

        # budowanie paska menu 
        menubar = swing.JMenuBar()
        file = swing.JMenu("File")
        file.add(swing.JMenuItem("Load", actionPerformed = self.do_load))
        file.add(swing.JMenuItem("Save", actionPerformed = self.do_save))
        file.add(swing.JMenuItem("Quit", actionPerformed = self.do_quit))
        menubar.add(file)
        self.frame.JMenuBar = menubar

        # tworzenie widetw
        self.chart = Chart(visible=1)
        self.execentry = swing.JTextArea(default_setup, 8, 60)
        self.evalentry = swing.JTextField(default_expression,
                                          actionPerformed = self.update)

        # tworzenie panelu opcji
        optionsPanel = swing.JPanel(awt.FlowLayout(
            alignment=awt.FlowLayout.LEFT))

        # czy wykres jest wykresem liniowym, czy wykresem wypenionym?
        self.filled = swing.JRadioButton("Filled",
                                         actionPerformed=self.set_filled)
        optionsPanel.add(self.filled)
        self.line = swing.JRadioButton("Line",
                                        actionPerformed=self.set_line)
        optionsPanel.add(self.line)
        styleGroup = swing.ButtonGroup()
        styleGroup.add(self.filled)
        styleGroup.add(self.line)

        # wybr koloru
        optionsPanel.add(swing.JLabel("Color:", RIGHT))
        colorlist = filter(lambda x: x[0] != '_', dir(colors))
        self.colorname = swing.JComboBox(colorlist)
        self.colorname.itemStateChanged = self.set_color
        optionsPanel.add(self.colorname)

        # liczba punktw
        optionsPanel.add(swing.JLabel("Number of Points:", RIGHT))
        self.sizes = [50, 100, 200, 500]
        self.numpoints = swing.JComboBox(self.sizes)
        self.numpoints.selectedIndex = self.sizes.index(self.numelements)
        self.numpoints.itemStateChanged = self.set_numpoints
        optionsPanel.add(self.numpoints)

        # dopieszczenie wygldu w GridBag
        self.do_layout(optionsPanel)

    def do_layout(self, optionsPanel):
        bag = GridBag(self.frame.contentPane, fill='BOTH',
                      weightx=1.0, weighty=1.0)
        bag.add(swing.JLabel("Setup Code: ", RIGHT))
        bag.addRow(swing.JScrollPane(self.execentry), weighty=10.0)
        bag.add(swing.JLabel("Expression: ", RIGHT))
        bag.addRow(self.evalentry, weighty=2.0)
        bag.add(swing.JLabel("Output: ", RIGHT))
        bag.addRow(self.chart, weighty=20.0)
        bag.add(swing.JLabel("Options: ", RIGHT))
        bag.addRow(optionsPanel, weighty=2.0)
        self.update(None)
        self.frame.visible = 1
        self.frame.size = self.frame.getPreferredSize()

        self.chooser = swing.JFileChooser()
        self.chooser.currentDirectory = java.io.File(os.getcwd())

    def do_save(self, event=None):
        self.chooser.rescanCurrentDirectory()
        returnVal = self.chooser.showSaveDialog(self.frame)
        if returnVal == APPROVE_OPTION:
            object = (self.execentry.text, self.evalentry.text,
                      self.chart.style,
                      self.chart.color.RGB,
                      self.colorname.selectedIndex,
                      self.numelements)
            file = open(os.path.join(self.chooser.currentDirectory.path,
                        self.chooser.selectedFile.name), 'w')
            pickle.dump(object, file)
            file.close()

    def do_load(self, event=None):
        self.chooser.rescanCurrentDirectory()
        returnVal = self.chooser.showOpenDialog(self.frame)
        if returnVal == APPROVE_OPTION:
            file = open(os.path.join(self.chooser.currentDirectory.path,
                     self.chooser.selectedFile.name))
            (setup, each, style, color,
             colorname, self.numelements) = pickle.load(file)
            file.close()
            self.chart.color = java.awt.Color(color)
            self.colorname.selectedIndex = colorname
            self.chart.style = style
            self.execentry.text = setup
            self.numpoints.selectedIndex = self.sizes.index(self.numelements)
            self.evalentry.text = each
            self.update(None)

    def do_quit(self, event=None):
        import sys
        sys.exit(0)

    def set_color(self, event):
        self.chart.color = getattr(colors, event.item)
        self.chart.repaint()

    def set_numpoints(self, event):
        self.numelements = event.item
        self.update(None)

    def set_filled(self, event):
        self.chart.style = 'Filled'
        self.chart.repaint()

    def set_line(self, event):
        self.chart.style = 'Line'
        self.chart.repaint()

    def update(self, event):
        context = {}
        exec self.execentry.text in context
        each = compile(self.evalentry.text, '<input>', 'eval')
        numbers = [0]*self.numelements
        for x in range(self.numelements):
            context['x'] = float(x)
            numbers[x] = eval(each, context)
        self.chart.data = numbers
        if self.chart.style == 'Line':
            self.line.setSelected(1)
        else:
            self.filled.setSelected(1)
        self.chart.repaint()

GUI()


*** Strona 306 *******************************************************************

from Numeric import *
coords = arange(-6, 6, .02)                # tworzy zakres wsprzdnych
xs = sin(coords)                           # pobiera sinus wszystkich x
ys = cos(coords)*exp(-coords*coords/18.0)  # pobiera zespolon funkcj z y
zs = xs * ys[:,NewAxis]                    # mnoy wiersz x przez kolumn y


***kod do wicze znajduje si w katalogu "rozwiazania"***