frescobaldi / python-poppler-qt4

Python binding to poppler-qt4
Other
28 stars 13 forks source link

linkDestination fails #4

Closed C9t0 closed 9 years ago

C9t0 commented 9 years ago

Hi there, i have write a little recursive function to reads in a table of content and i try to get the pageNumber for each chapter via the linkDestination function. But the link call will always return 0 and a error message: "failed to look up ..."

I use Ubuntu 14.04 with the latest python3 version (3.4.0) and with installed poppler and qt4 packages from the ubuntu repo and i have only install python-poppler-qt4 alternative via pip3

I have try this on some more eBooks with large ToC's and always i would get this messages!

The readToc funcktion looks like:

def __readToC(doc, inChapter: Chapter, node):
    n = node.firstChildElement()
    while(not n.isNull()):
        #build up this chapter
        subChapter = Chapter()

        subChapter.title = n.tagName()

        linkDest = doc.linkDestination(n.attribute("Destination"))
        subChapter.startPage = linkDest.pageNumber()-1

        #fill children
        Book.__readToC(doc, subChapter, n)

        inChapter.chapters.append(subChapter)

        n = n.nextSiblingElement()

and a print of from the toc and the link error message looks like:

<Table of Contents Destination="1;7;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
<Preface Destination="1;25;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
 <“And Now for Something Completely Different…” Destination="1;25;0;1.00076;0;0.291761;0;0;1;0" Open="false"/>
 <About This Book Destination="1;26;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <This Book’s Ecosystem Destination="1;26;0;1.00076;0;0.21164;0;0;1;0" Open="false"/>
  <What This Book Is Not Destination="1;27;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
 </About This Book>
 <About This Fourth Edition Destination="1;27;0;1.00076;0;0.588057;0;0;1;0" Open="false">
  <Specific Changes in This Edition Destination="1;28;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
 </About This Fourth Edition>
 <What’s Left, Then? Destination="1;32;0;1.00076;0;0.544218;0;0;1;0" Open="false"/>
 <Python 3.X Impacts on This Book Destination="1;33;0;1.00076;0;0.485261;0;0;1;0" Open="false">
  <Specific 3.X Changes Destination="1;34;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  <Language Versus Library: Unicode Destination="1;35;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  <Python 3.1 Limitations: Email, CGI Destination="1;35;0;1.00076;0;0.643991;0;0;1;0" Open="false"/>
 </Python 3.X Impacts on This Book>
 <Using Book Examples Destination="1;36;0;1.00076;0;0.604686;0;0;1;0" Open="false">
  <Where to Look for Examples and Updates Destination="1;36;0;1.00076;0;0.702948;0;0;1;0" Open="false"/>
  <Example Portability Destination="1;37;0;1.00076;0;0.489796;0;0;1;0" Open="false"/>
  <Demo Launchers Destination="1;38;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  <Code Reuse Policies Destination="1;38;0;1.00076;0;0.243386;0;0;1;0" Open="false"/>
 </Using Book Examples>
 <Contacting O’Reilly Destination="1;38;0;1.00076;0;0.527589;0;0;1;0" Open="false"/>
 <Conventions Used in This Book Destination="1;39;0;1.00076;0;0.145125;0;0;1;0" Open="false"/>
 <Acknowledgments Destination="1;39;0;1.00076;0;0.594104;0;0;1;0" Open="false"/>
</Preface>
<Part I. The Beginning Destination="1;43;0;1.00076;0;0.0786092;0;0;1;0" Open="false">
 <Chapter 1. A Sneak Preview Destination="1;45;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Programming Python: The Short Story” Destination="1;45;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <The Task Destination="1;46;0;1.00076;0;0.272109;0;0;1;0" Open="false"/>
  <Step 1: Representing Records Destination="1;46;0;1.00076;0;0.56387;0;0;1;0" Open="false">
   <Using Lists Destination="1;46;0;1.00076;0;0.699924;0;0;1;0" Open="false">
    <Start-up pointers Destination="1;47;0;1.00076;0;0.402116;0;0;1;0" Open="false"/>
    <A database list Destination="1;48;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Field labels Destination="1;49;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
   </Using Lists>
   <Using Dictionaries Destination="1;51;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Other ways to make dictionaries Destination="1;51;0;1.00076;0;0.509448;0;0;1;0" Open="false"/>
    <Lists of dictionaries Destination="1;52;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
    <Nested structures Destination="1;53;0;1.00076;0;0.547241;0;0;1;0" Open="false"/>
    <Dictionaries of dictionaries Destination="1;54;0;1.00076;0;0.513983;0;0;1;0" Open="false"/>
   </Using Dictionaries>
  </Step 1: Representing Records>
  <Step 2: Storing Records Persistently Destination="1;56;0;1.00076;0;0.450491;0;0;1;0" Open="false">
   <Using Formatted Files Destination="1;56;0;1.00076;0;0.604686;0;0;1;0" Open="false">
    <Test data script Destination="1;56;0;1.00076;0;0.715042;0;0;1;0" Open="false"/>
    <File name conventions Destination="1;57;0;1.00076;0;0.61678;0;0;1;0" Open="false"/>
    <Script start-up pointers Destination="1;58;0;1.00076;0;0.256992;0;0;1;0" Open="false"/>
    <Data format script Destination="1;58;0;1.00076;0;0.70446;0;0;1;0" Open="false"/>
    <Utility scripts Destination="1;60;0;1.00076;0;0.657596;0;0;1;0" Open="false"/>
   </Using Formatted Files>
   <Using Pickle Files Destination="1;61;0;1.00076;0;0.637944;0;0;1;0" Open="false"/>
   <Using Per-Record Pickle Files Destination="1;64;0;1.00076;0;0.137566;0;0;1;0" Open="false"/>
   <Using Shelves Destination="1;65;0;1.00076;0;0.491308;0;0;1;0" Open="false"/>
  </Step 2: Storing Records Persistently>
  <Step 3: Stepping Up to OOP Destination="1;68;0;1.00076;0;0.338624;0;0;1;0" Open="false">
   <Using Classes Destination="1;69;0;1.00076;0;0.70446;0;0;1;0" Open="false"/>
   <Adding Behavior Destination="1;71;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
   <Adding Inheritance Destination="1;71;0;1.00076;0;0.781557;0;0;1;0" Open="false"/>
   <Refactoring Code Destination="1;73;0;1.00076;0;0.21164;0;0;1;0" Open="false">
    <Augmenting methods Destination="1;73;0;1.00076;0;0.303855;0;0;1;0" Open="false"/>
    <Display format Destination="1;73;0;1.00076;0;0.777022;0;0;1;0" Open="false"/>
    <Constructor customization Destination="1;74;0;1.00076;0;0.39607;0;0;1;0" Open="false"/>
    <Alternative classes Destination="1;74;0;1.00076;0;0.718065;0;0;1;0" Open="false"/>
   </Refactoring Code>
   <Adding Persistence Destination="1;76;0;1.00076;0;0.229781;0;0;1;0" Open="false"/>
   <Other Database Options Destination="1;78;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
  </Step 3: Stepping Up to OOP>
  <Step 4: Adding Console Interaction Destination="1;79;0;1.00076;0;0.320484;0;0;1;0" Open="false">
   <A Console Shelve Interface Destination="1;79;0;1.00076;0;0.494331;0;0;1;0" Open="false"/>
  </Step 4: Adding Console Interaction>
  <Step 5: Adding a GUI Destination="1;82;0;1.00076;0;0.154195;0;0;1;0" Open="false">
   <GUI Basics Destination="1;82;0;1.00076;0;0.290249;0;0;1;0" Open="false"/>
   <Using OOP for GUIs Destination="1;84;0;1.00076;0;0.373394;0;0;1;0" Open="false"/>
   <Getting Input from a User Destination="1;86;0;1.00076;0;0.671202;0;0;1;0" Open="false"/>
   <A GUI Shelve Interface Destination="1;88;0;1.00076;0;0.119426;0;0;1;0" Open="false">
    <Coding the GUI Destination="1;88;0;1.00076;0;0.574452;0;0;1;0" Open="false"/>
    <Using the GUI Destination="1;90;0;1.00076;0;0.191988;0;0;1;0" Open="false"/>
    <Future directions Destination="1;91;0;1.00076;0;0.628874;0;0;1;0" Open="false"/>
   </A GUI Shelve Interface>
  </Step 5: Adding a GUI>
  <Step 6: Adding a Web Interface Destination="1;94;0;1.00076;0;0.1678;0;0;1;0" Open="false">
   <CGI Basics Destination="1;94;0;1.00076;0;0.715042;0;0;1;0" Open="false">
    <GUIs versus the Web Destination="1;97;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
   </CGI Basics>
   <Running a Web Server Destination="1;97;0;1.00076;0;0.622827;0;0;1;0" Open="false"/>
   <Using Query Strings and urllib Destination="1;99;0;1.00076;0;0.780045;0;0;1;0" Open="false"/>
   <Formatting Reply Text Destination="1;101;0;1.00076;0;0.331066;0;0;1;0" Open="false"/>
   <A Web-Based Shelve Interface Destination="1;102;0;1.00076;0;0.155707;0;0;1;0" Open="false">
    <Coding the website Destination="1;102;0;1.00076;0;0.592593;0;0;1;0" Open="false"/>
    <Directories, string formatting, and security Destination="1;105;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Using the website Destination="1;106;0;1.00076;0;0.604686;0;0;1;0" Open="false"/>
    <Future directions Destination="1;110;0;1.00076;0;0.737717;0;0;1;0" Open="false"/>
   </A Web-Based Shelve Interface>
  </Step 6: Adding a Web Interface>
  <The End of the Demo Destination="1;111;0;1.00076;0;0.654573;0;0;1;0" Open="false"/>
 </Chapter 1. A Sneak Preview>
</Part I. The Beginning>
<Part II. System Programming Destination="1;113;0;1.00076;0;0.0786092;0;0;1;0" Open="false">
 <Chapter 2. System Tools Destination="1;115;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“The os.path to Knowledge” Destination="1;115;0;1.00076;0;0.320484;0;0;1;0" Open="false">
   <Why Python Here? Destination="1;115;0;1.00076;0;0.569917;0;0;1;0" Open="false"/>
   <The Next Five Chapters Destination="1;116;0;1.00076;0;0.273621;0;0;1;0" Open="false"/>
  </“The os.path to Knowledge”>
  <System Scripting Overview Destination="1;117;0;1.00076;0;0.637944;0;0;1;0" Open="false">
   <Python System Modules Destination="1;118;0;1.00076;0;0.473167;0;0;1;0" Open="false"/>
   <Module Documentation Sources Destination="1;119;0;1.00076;0;0.393046;0;0;1;0" Open="false"/>
   <Paging Documentation Strings Destination="1;120;0;1.00076;0;0.321995;0;0;1;0" Open="false"/>
   <A Custom Paging Script Destination="1;121;0;1.00076;0;0.3613;0;0;1;0" Open="false"/>
   <String Method Basics Destination="1;122;0;1.00076;0;0.393046;0;0;1;0" Open="false"/>
   <Other String Concepts in Python 3.X: Unicode and bytes Destination="1;124;0;1.00076;0;0.692366;0;0;1;0" Open="false"/>
   <File Operation Basics Destination="1;125;0;1.00076;0;0.585034;0;0;1;0" Open="false"/>
   <Using Programs in Two Ways Destination="1;126;0;1.00076;0;0.293273;0;0;1;0" Open="false"/>
   <Python Library Manuals Destination="1;127;0;1.00076;0;0.60771;0;0;1;0" Open="false"/>
   <Commercially Published References Destination="1;128;0;1.00076;0;0.220711;0;0;1;0" Open="false"/>
  </System Scripting Overview>
  <Introducing the sys Module Destination="1;128;0;1.00076;0;0.403628;0;0;1;0" Open="false">
   <Platforms and Versions Destination="1;128;0;1.00076;0;0.595616;0;0;1;0" Open="false"/>
   <The Module Search Path Destination="1;129;0;1.00076;0;0.288738;0;0;1;0" Open="false"/>
   <The Loaded Modules Table Destination="1;130;0;1.00076;0;0.609221;0;0;1;0" Open="false"/>
   <Exception Details Destination="1;131;0;1.00076;0;0.219199;0;0;1;0" Open="false"/>
   <Other sys Module Exports Destination="1;132;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  </Introducing the sys Module>
  <Introducing the os Module Destination="1;132;0;1.00076;0;0.250945;0;0;1;0" Open="false">
   <Tools in the os Module Destination="1;132;0;1.00076;0;0.480726;0;0;1;0" Open="false"/>
   <Administrative Tools Destination="1;133;0;1.00076;0;0.485261;0;0;1;0" Open="false"/>
   <Portability Constants Destination="1;134;0;1.00076;0;0.21164;0;0;1;0" Open="false"/>
   <Common os.path Tools Destination="1;134;0;1.00076;0;0.677249;0;0;1;0" Open="false"/>
   <Running Shell Commands from Scripts Destination="1;136;0;1.00076;0;0.761905;0;0;1;0" Open="false">
    <What’s a shell command? Destination="1;137;0;1.00076;0;0.288738;0;0;1;0" Open="false"/>
    <Running shell commands Destination="1;137;0;1.00076;0;0.736206;0;0;1;0" Open="false"/>
    <Communicating with shell commands Destination="1;138;0;1.00076;0;0.474679;0;0;1;0" Open="false"/>
    <The subprocess module alternative Destination="1;139;0;1.00076;0;0.488284;0;0;1;0" Open="false"/>
    <Shell command limitations Destination="1;141;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
   </Running Shell Commands from Scripts>
   <Other os Module Exports Destination="1;142;0;1.00076;0;0.445956;0;0;1;0" Open="false"/>
  </Introducing the os Module>
 </Chapter 2. System Tools>
 <Chapter 3. Script Execution Context Destination="1;145;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“I’d Like to Have an Argument, Please” Destination="1;145;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <Current Working Directory Destination="1;146;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <CWD, Files, and Import Paths Destination="1;146;0;1.00076;0;0.331066;0;0;1;0" Open="false"/>
   <CWD and Command Lines Destination="1;148;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  </Current Working Directory>
  <Command-Line Arguments Destination="1;148;0;1.00076;0;0.622827;0;0;1;0" Open="false">
   <Parsing Command-Line Arguments Destination="1;149;0;1.00076;0;0.636432;0;0;1;0" Open="false"/>
  </Command-Line Arguments>
  <Shell Environment Variables Destination="1;151;0;1.00076;0;0.710506;0;0;1;0" Open="false">
   <Fetching Shell Variables Destination="1;152;0;1.00076;0;0.191988;0;0;1;0" Open="false"/>
   <Changing Shell Variables Destination="1;153;0;1.00076;0;0.137566;0;0;1;0" Open="false"/>
   <Shell Variable Fine Points: Parents, putenv, and getenv Destination="1;154;0;1.00076;0;0.643991;0;0;1;0" Open="false"/>
  </Shell Environment Variables>
  <Standard Streams Destination="1;155;0;1.00076;0;0.429327;0;0;1;0" Open="false">
   <Redirecting Streams to Files and Programs Destination="1;156;0;1.00076;0;0.50189;0;0;1;0" Open="false">
    <Chaining programs with pipes Destination="1;158;0;1.00076;0;0.362812;0;0;1;0" Open="false"/>
    <Coding alternatives for adders and sorters Destination="1;160;0;1.00076;0;0.432351;0;0;1;0" Open="false"/>
   </Redirecting Streams to Files and Programs>
   <Redirected Streams and User Interaction Destination="1;161;0;1.00076;0;0.46712;0;0;1;0" Open="false"/>
   <Redirecting Streams to Python Objects Destination="1;165;0;1.00076;0;0.219199;0;0;1;0" Open="false"/>
   <The io.StringIO and io.BytesIO Utility Classes Destination="1;168;0;1.00076;0;0.285714;0;0;1;0" Open="false"/>
   <Capturing the stderr Stream Destination="1;169;0;1.00076;0;0.373394;0;0;1;0" Open="false"/>
   <Redirection Syntax in Print Calls Destination="1;169;0;1.00076;0;0.721088;0;0;1;0" Open="false"/>
   <Other Redirection Options: os.popen and subprocess Revisited Destination="1;170;0;1.00076;0;0.500378;0;0;1;0" Open="false">
    <Redirecting input or output with os.popen Destination="1;171;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Redirecting input and output with subprocess Destination="1;172;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Other Redirection Options: os.popen and subprocess Revisited>
  </Standard Streams>
 </Chapter 3. Script Execution Context>
 <Chapter 4. File and Directory Tools Destination="1;177;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Erase Your Hard Drive in Five Easy Steps!” Destination="1;177;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <File Tools Destination="1;177;0;1.00076;0;0.524565;0;0;1;0" Open="false">
   <The File Object Model in Python 3.X Destination="1;178;0;1.00076;0;0.273621;0;0;1;0" Open="false"/>
   <Using Built-in File Objects Destination="1;179;0;1.00076;0;0.585034;0;0;1;0" Open="false">
    <Output files Destination="1;179;0;1.00076;0;0.787604;0;0;1;0" Open="false">
     <Opening Destination="1;180;0;1.00076;0;0.459562;0;0;1;0" Open="false"/>
     <Writing Destination="1;180;0;1.00076;0;0.677249;0;0;1;0" Open="false"/>
    </Output files>
    <Ensuring file closure: Exception handlers and context managers Destination="1;181;0;1.00076;0;0.761905;0;0;1;0" Open="false">
     <Closing Destination="1;181;0;1.00076;0;0.126984;0;0;1;0" Open="false"/>
    </Ensuring file closure: Exception handlers and context managers>
    <Input files Destination="1;183;0;1.00076;0;0.344671;0;0;1;0" Open="false"/>
    <Reading lines with file iterators Destination="1;185;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Other open options Destination="1;186;0;1.00076;0;0.577475;0;0;1;0" Open="false"/>
   </Using Built-in File Objects>
   <Binary and Text Files Destination="1;188;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Unicode encodings for text files Destination="1;189;0;1.00076;0;0.260015;0;0;1;0" Open="false"/>
    <End-of-line translations for text files Destination="1;191;0;1.00076;0;0.367347;0;0;1;0" Open="false"/>
    <Parsing packed binary data with the struct module Destination="1;193;0;1.00076;0;0.677249;0;0;1;0" Open="false"/>
    <Random access files Destination="1;195;0;1.00076;0;0.237339;0;0;1;0" Open="false"/>
   </Binary and Text Files>
   <Lower-Level File Tools in the os Module Destination="1;197;0;1.00076;0;0.622827;0;0;1;0" Open="false">
    <Using os.open files Destination="1;198;0;1.00076;0;0.294785;0;0;1;0" Open="false"/>
    <os.open mode flags Destination="1;199;0;1.00076;0;0.270597;0;0;1;0" Open="false"/>
    <Wrapping descriptors in file objects Destination="1;200;0;1.00076;0;0.293273;0;0;1;0" Open="false"/>
    <Other os module file tools Destination="1;201;0;1.00076;0;0.263039;0;0;1;0" Open="false"/>
   </Lower-Level File Tools in the os Module>
   <File Scanners Destination="1;202;0;1.00076;0;0.521542;0;0;1;0" Open="false">
    <File filters Destination="1;204;0;1.00076;0;0.468632;0;0;1;0" Open="false"/>
   </File Scanners>
  </File Tools>
  <Directory Tools Destination="1;205;0;1.00076;0;0.645503;0;0;1;0" Open="false">
   <Walking One Directory Destination="1;206;0;1.00076;0;0.173847;0;0;1;0" Open="false">
    <Running shell listing commands with os.popen Destination="1;206;0;1.00076;0;0.358277;0;0;1;0" Open="false"/>
    <The glob module Destination="1;208;0;1.00076;0;0.152683;0;0;1;0" Open="false"/>
    <The os.listdir call Destination="1;209;0;1.00076;0;0.226757;0;0;1;0" Open="false"/>
    <Splitting and joining listing results Destination="1;210;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Walking One Directory>
   <Walking Directory Trees Destination="1;210;0;1.00076;0;0.637944;0;0;1;0" Open="false">
    <The os.walk visitor Destination="1;211;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
    <Recursive os.listdir traversals Destination="1;213;0;1.00076;0;0.66969;0;0;1;0" Open="false"/>
   </Walking Directory Trees>
   <Handling Unicode Filenames in 3.X: listdir, walk, glob Destination="1;214;0;1.00076;0;0.761905;0;0;1;0" Open="false">
    <Unicode policies: File content versus file names Destination="1;216;0;1.00076;0;0.318972;0;0;1;0" Open="false"/>
   </Handling Unicode Filenames in 3.X: listdir, walk, glob>
  </Directory Tools>
 </Chapter 4. File and Directory Tools>
 <Chapter 5. Parallel System Tools Destination="1;219;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Telling the Monkeys What to Do” Destination="1;219;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <Forking Processes Destination="1;221;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <The fork/exec Combination Destination="1;224;0;1.00076;0;0.282691;0;0;1;0" Open="false">
    <os.exec call formats Destination="1;225;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Spawned child program Destination="1;226;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </The fork/exec Combination>
  </Forking Processes>
  <Threads Destination="1;228;0;1.00076;0;0.377929;0;0;1;0" Open="false">
   <The _thread Module Destination="1;231;0;1.00076;0;0.474679;0;0;1;0" Open="false">
    <Basic usage Destination="1;231;0;1.00076;0;0.636432;0;0;1;0" Open="false"/>
    <Other ways to code threads with _thread Destination="1;233;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
    <Running multiple threads Destination="1;233;0;1.00076;0;0.693878;0;0;1;0" Open="false"/>
    <Synchronizing access to shared objects and names Destination="1;235;0;1.00076;0;0.61678;0;0;1;0" Open="false"/>
    <Waiting for spawned thread exits Destination="1;237;0;1.00076;0;0.656085;0;0;1;0" Open="false"/>
    <Coding alternatives: busy loops, arguments, and context managers Destination="1;239;0;1.00076;0;0.692366;0;0;1;0" Open="false"/>
   </The _thread Module>
   <The threading Module Destination="1;241;0;1.00076;0;0.471655;0;0;1;0" Open="false">
    <Other ways to code threads with threading Destination="1;243;0;1.00076;0;0.329554;0;0;1;0" Open="false"/>
    <Synchronizing access to shared objects and names revisited Destination="1;244;0;1.00076;0;0.532124;0;0;1;0" Open="false"/>
   </The threading Module>
   <The queue Module Destination="1;246;0;1.00076;0;0.701436;0;0;1;0" Open="false">
    <Arguments versus globals Destination="1;248;0;1.00076;0;0.157218;0;0;1;0" Open="false"/>
    <Program exit with child threads Destination="1;248;0;1.00076;0;0.524565;0;0;1;0" Open="false"/>
    <Running the script Destination="1;249;0;1.00076;0;0.536659;0;0;1;0" Open="false"/>
   </The queue Module>
   <Preview: GUIs and Threads Destination="1;250;0;1.00076;0;0.631897;0;0;1;0" Open="false"/>
   <More on the Global Interpreter Lock Destination="1;253;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <The thread switch interval Destination="1;254;0;1.00076;0;0.25548;0;0;1;0" Open="false"/>
    <Atomic operations Destination="1;254;0;1.00076;0;0.474679;0;0;1;0" Open="false"/>
    <C API thread considerations Destination="1;254;0;1.00076;0;0.805745;0;0;1;0" Open="false"/>
    <A process-based alternative: multiprocessing (ahead) Destination="1;255;0;1.00076;0;0.411187;0;0;1;0" Open="false"/>
   </More on the Global Interpreter Lock>
  </Threads>
  <Program Exits Destination="1;255;0;1.00076;0;0.742252;0;0;1;0" Open="false">
   <sys Module Exits Destination="1;256;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
   <os Module Exits Destination="1;257;0;1.00076;0;0.270597;0;0;1;0" Open="false"/>
   <Shell Command Exit Status Codes Destination="1;258;0;1.00076;0;0.182918;0;0;1;0" Open="false">
    <Exit status with os.system and os.popen Destination="1;258;0;1.00076;0;0.737717;0;0;1;0" Open="false"/>
    <Output stream buffering: A first look Destination="1;260;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Exit status with subprocess Destination="1;260;0;1.00076;0;0.698413;0;0;1;0" Open="false"/>
   </Shell Command Exit Status Codes>
   <Process Exit Status and Shared State Destination="1;261;0;1.00076;0;0.524565;0;0;1;0" Open="false"/>
   <Thread Exits and Shared State Destination="1;262;0;1.00076;0;0.640967;0;0;1;0" Open="false"/>
  </Program Exits>
  <Interprocess Communication Destination="1;264;0;1.00076;0;0.613757;0;0;1;0" Open="false">
   <Anonymous Pipes Destination="1;266;0;1.00076;0;0.199546;0;0;1;0" Open="false">
    <Anonymous pipe basics Destination="1;266;0;1.00076;0;0.666667;0;0;1;0" Open="false"/>
    <Wrapping pipe descriptors in file objects Destination="1;268;0;1.00076;0;0.285714;0;0;1;0" Open="false"/>
    <Anonymous pipes and threads Destination="1;269;0;1.00076;0;0.690854;0;0;1;0" Open="false"/>
    <Bidirectional IPC with anonymous pipes Destination="1;270;0;1.00076;0;0.656085;0;0;1;0" Open="false"/>
    <Output stream buffering revisited: Deadlocks and flushes Destination="1;273;0;1.00076;0;0.559335;0;0;1;0" Open="false"/>
   </Anonymous Pipes>
   <Named Pipes (Fifos) Destination="1;276;0;1.00076;0;0.226757;0;0;1;0" Open="false">
    <Named pipe basics Destination="1;277;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Named pipe use cases Destination="1;278;0;1.00076;0;0.415722;0;0;1;0" Open="false"/>
   </Named Pipes (Fifos)>
   <Sockets: A First Look Destination="1;278;0;1.00076;0;0.698413;0;0;1;0" Open="false">
    <Socket basics Destination="1;279;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Sockets and independent programs Destination="1;280;0;1.00076;0;0.592593;0;0;1;0" Open="false"/>
    <Socket use cases Destination="1;281;0;1.00076;0;0.760393;0;0;1;0" Open="false"/>
   </Sockets: A First Look>
   <Signals Destination="1;282;0;1.00076;0;0.592593;0;0;1;0" Open="false"/>
  </Interprocess Communication>
  <The multiprocessing Module Destination="1;285;0;1.00076;0;0.504913;0;0;1;0" Open="false">
   <Why multiprocessing? Destination="1;285;0;1.00076;0;0.796674;0;0;1;0" Open="false"/>
   <The Basics: Processes and Locks Destination="1;287;0;1.00076;0;0.518519;0;0;1;0" Open="false">
    <Implementation and usage rules Destination="1;288;0;1.00076;0;0.758881;0;0;1;0" Open="false"/>
   </The Basics: Processes and Locks>
   <IPC Tools: Pipes, Shared Memory, and Queues Destination="1;290;0;1.00076;0;0.119426;0;0;1;0" Open="false">
    <multiprocessing pipes Destination="1;291;0;1.00076;0;0.219199;0;0;1;0" Open="false"/>
    <Shared memory and globals Destination="1;292;0;1.00076;0;0.287226;0;0;1;0" Open="false"/>
    <Queues and subclassing Destination="1;294;0;1.00076;0;0.619803;0;0;1;0" Open="false"/>
   </IPC Tools: Pipes, Shared Memory, and Queues>
   <Starting Independent Programs Destination="1;296;0;1.00076;0;0.595616;0;0;1;0" Open="false"/>
   <And Much More Destination="1;298;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <And a little less… Destination="1;298;0;1.00076;0;0.60771;0;0;1;0" Open="false"/>
   </And Much More>
   <Why multiprocessing? The Conclusion Destination="1;299;0;1.00076;0;0.504913;0;0;1;0" Open="false"/>
  </The multiprocessing Module>
  <Other Ways to Start Programs Destination="1;300;0;1.00076;0;0.155707;0;0;1;0" Open="false">
   <The os.spawn Calls Destination="1;300;0;1.00076;0;0.328042;0;0;1;0" Open="false"/>
   <The os.startfile call on Windows Destination="1;303;0;1.00076;0;0.479214;0;0;1;0" Open="false">
    <Using the DOS start command Destination="1;303;0;1.00076;0;0.645503;0;0;1;0" Open="false"/>
    <Using start in Python scripts Destination="1;304;0;1.00076;0;0.473167;0;0;1;0" Open="false"/>
    <The os.startfile call Destination="1;305;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </The os.startfile call on Windows>
  </Other Ways to Start Programs>
  <A Portable Program-Launch Framework Destination="1;305;0;1.00076;0;0.542706;0;0;1;0" Open="false"/>
  <Other System Tools Coverage Destination="1;310;0;1.00076;0;0.318972;0;0;1;0" Open="false"/>
 </Chapter 5. Parallel System Tools>
 <Chapter 6. Complete System Programs Destination="1;313;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“The Greps of Wrath” Destination="1;313;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <A Quick Game of “Find the Biggest Python File” Destination="1;314;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <Scanning the Standard Library Directory Destination="1;314;0;1.00076;0;0.249433;0;0;1;0" Open="false"/>
   <Scanning the Standard Library Tree Destination="1;315;0;1.00076;0;0.154195;0;0;1;0" Open="false"/>
   <Scanning the Module Search Path Destination="1;316;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Scanning the Entire Machine Destination="1;318;0;1.00076;0;0.137566;0;0;1;0" Open="false"/>
   <Printing Unicode Filenames Destination="1;321;0;1.00076;0;0.764928;0;0;1;0" Open="false"/>
  </A Quick Game of “Find the Biggest Python File”>
  <Splitting and Joining Files Destination="1;324;0;1.00076;0;0.347695;0;0;1;0" Open="false">
   <Splitting Files Portably Destination="1;325;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
   <Joining Files Portably Destination="1;328;0;1.00076;0;0.479214;0;0;1;0" Open="false"/>
   <Usage Variations Destination="1;331;0;1.00076;0;0.270597;0;0;1;0" Open="false"/>
  </Splitting and Joining Files>
  <Generating Redirection Web Pages Destination="1;334;0;1.00076;0;0.681784;0;0;1;0" Open="false">
   <Page Template File Destination="1;335;0;1.00076;0;0.51096;0;0;1;0" Open="false"/>
   <Page Generator Script Destination="1;336;0;1.00076;0;0.350718;0;0;1;0" Open="false"/>
  </Generating Redirection Web Pages>
  <A Regression Test Script Destination="1;339;0;1.00076;0;0.155707;0;0;1;0" Open="false">
   <Running the Test Driver Destination="1;341;0;1.00076;0;0.56387;0;0;1;0" Open="false"/>
  </A Regression Test Script>
  <Copying Directory Trees Destination="1;346;0;1.00076;0;0.630385;0;0;1;0" Open="false"/>
  <Comparing Directory Trees Destination="1;350;0;1.00076;0;0.479214;0;0;1;0" Open="false">
   <Finding Directory Differences Destination="1;351;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
   <Finding Tree Differences Destination="1;353;0;1.00076;0;0.373394;0;0;1;0" Open="false"/>
   <Running the Script Destination="1;356;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Verifying Backups Destination="1;358;0;1.00076;0;0.1935;0;0;1;0" Open="false"/>
   <Reporting Differences and Other Ideas Destination="1;359;0;1.00076;0;0.746788;0;0;1;0" Open="false"/>
  </Comparing Directory Trees>
  <Searching Directory Trees Destination="1;361;0;1.00076;0;0.610733;0;0;1;0" Open="false">
   <Greps and Globs and Finds Destination="1;362;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
   <Rolling Your Own find Module Destination="1;363;0;1.00076;0;0.187453;0;0;1;0" Open="false">
    <The fnmatch module Destination="1;365;0;1.00076;0;0.485261;0;0;1;0" Open="false"/>
   </Rolling Your Own find Module>
   <Cleaning Up Bytecode Files Destination="1;366;0;1.00076;0;0.770975;0;0;1;0" Open="false"/>
   <A Python Tree Searcher Destination="1;369;0;1.00076;0;0.506425;0;0;1;0" Open="false"/>
  </Searching Directory Trees>
  <Visitor: Walking Directories “++” Destination="1;372;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <Editing Files in Directory Trees (Visitor) Destination="1;376;0;1.00076;0;0.677249;0;0;1;0" Open="false"/>
   <Global Replacements in Directory Trees (Visitor) Destination="1;378;0;1.00076;0;0.241875;0;0;1;0" Open="false"/>
   <Counting Source Code Lines (Visitor) Destination="1;380;0;1.00076;0;0.191988;0;0;1;0" Open="false"/>
   <Recoding Copies with Classes (Visitor) Destination="1;381;0;1.00076;0;0.742252;0;0;1;0" Open="false"/>
   <Other Visitor Examples (External) Destination="1;383;0;1.00076;0;0.588057;0;0;1;0" Open="false"/>
  </Visitor: Walking Directories “++”>
  <Playing Media Files Destination="1;385;0;1.00076;0;0.329554;0;0;1;0" Open="false">
   <The Python webbrowser Module Destination="1;389;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
   <The Python mimetypes Module Destination="1;390;0;1.00076;0;0.347695;0;0;1;0" Open="false">
    <Using mimetypes guesses for SearchVisitor Destination="1;391;0;1.00076;0;0.707483;0;0;1;0" Open="false"/>
   </The Python mimetypes Module>
   <Running the Script Destination="1;392;0;1.00076;0;0.719577;0;0;1;0" Open="false"/>
  </Playing Media Files>
  <Automated Program Launchers (External) Destination="1;393;0;1.00076;0;0.367347;0;0;1;0" Open="false"/>
 </Chapter 6. Complete System Programs>
</Part II. System Programming>
<Part III. GUI Programming Destination="1;395;0;1.00076;0;0.0786092;0;0;1;0" Open="false">
 <Chapter 7. Graphical User Interfaces Destination="1;397;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Here’s Looking at You, Kid” Destination="1;397;0;1.00076;0;0.320484;0;0;1;0" Open="false">
   <GUI Programming Topics Destination="1;397;0;1.00076;0;0.62585;0;0;1;0" Open="false"/>
   <Running the Examples Destination="1;399;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  </“Here’s Looking at You, Kid”>
  <Python GUI Development Options Destination="1;400;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  <tkinter Overview Destination="1;405;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <tkinter Pragmatics Destination="1;405;0;1.00076;0;0.229781;0;0;1;0" Open="false"/>
   <tkinter Documentation Destination="1;406;0;1.00076;0;0.137566;0;0;1;0" Open="false"/>
   <tkinter Extensions Destination="1;406;0;1.00076;0;0.659108;0;0;1;0" Open="false"/>
   <tkinter Structure Destination="1;408;0;1.00076;0;0.622827;0;0;1;0" Open="false">
    <Implementation structure Destination="1;408;0;1.00076;0;0.751323;0;0;1;0" Open="false"/>
    <Programming structure Destination="1;409;0;1.00076;0;0.374906;0;0;1;0" Open="false"/>
   </tkinter Structure>
  </tkinter Overview>
  <Climbing the GUI Learning Curve Destination="1;410;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <“Hello World” in Four Lines (or Less) Destination="1;410;0;1.00076;0;0.1935;0;0;1;0" Open="false"/>
   <tkinter Coding Basics Destination="1;411;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Making Widgets Destination="1;412;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Geometry Managers Destination="1;412;0;1.00076;0;0.432351;0;0;1;0" Open="false"/>
   <Running GUI Programs Destination="1;413;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Avoiding DOS consoles on Windows Destination="1;413;0;1.00076;0;0.491308;0;0;1;0" Open="false"/>
   </Running GUI Programs>
  </Climbing the GUI Learning Curve>
  <tkinter Coding Alternatives Destination="1;414;0;1.00076;0;0.21164;0;0;1;0" Open="false">
   <Widget Resizing Basics Destination="1;415;0;1.00076;0;0.643991;0;0;1;0" Open="false"/>
   <Configuring Widget Options and Window Titles Destination="1;417;0;1.00076;0;0.473167;0;0;1;0" Open="false"/>
   <One More for Old Times’ Sake Destination="1;418;0;1.00076;0;0.733182;0;0;1;0" Open="false"/>
   <Packing Widgets Without Saving Them Destination="1;419;0;1.00076;0;0.397581;0;0;1;0" Open="false"/>
  </tkinter Coding Alternatives>
  <Adding Buttons and Callbacks Destination="1;421;0;1.00076;0;0.175359;0;0;1;0" Open="false">
   <Widget Resizing Revisited: Expansion Destination="1;422;0;1.00076;0;0.489796;0;0;1;0" Open="false"/>
  </Adding Buttons and Callbacks>
  <Adding User-Defined Callback Handlers Destination="1;424;0;1.00076;0;0.191988;0;0;1;0" Open="false">
   <Lambda Callback Handlers Destination="1;425;0;1.00076;0;0.40514;0;0;1;0" Open="false"/>
   <Deferring Calls with Lambdas and Object References Destination="1;426;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Callback Scope Issues Destination="1;427;0;1.00076;0;0.523054;0;0;1;0" Open="false">
    <Arguments versus globals Destination="1;427;0;1.00076;0;0.65155;0;0;1;0" Open="false"/>
    <Passing in enclosing scope values with default arguments Destination="1;428;0;1.00076;0;0.273621;0;0;1;0" Open="false"/>
    <Passing in enclosing scope values with automatic references Destination="1;429;0;1.00076;0;0.199546;0;0;1;0" Open="false"/>
    <But you must still sometimes use defaults instead of enclosing scopes Destination="1;429;0;1.00076;0;0.77551;0;0;1;0" Open="false"/>
   </Callback Scope Issues>
   <Bound Method Callback Handlers Destination="1;433;0;1.00076;0;0.293273;0;0;1;0" Open="false"/>
   <Callable Class Object Callback Handlers Destination="1;434;0;1.00076;0;0.347695;0;0;1;0" Open="false"/>
   <Other tkinter Callback Protocols Destination="1;435;0;1.00076;0;0.305367;0;0;1;0" Open="false"/>
   <Binding Events Destination="1;436;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
  </Adding User-Defined Callback Handlers>
  <Adding Multiple Widgets Destination="1;437;0;1.00076;0;0.137566;0;0;1;0" Open="false">
   <Widget Resizing Revisited: Clipping Destination="1;438;0;1.00076;0;0.157218;0;0;1;0" Open="false"/>
   <Attaching Widgets to Frames Destination="1;439;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
   <Layout: Packing Order and Side Attachments Destination="1;439;0;1.00076;0;0.521542;0;0;1;0" Open="false"/>
   <The Packer’s Expand and Fill Revisited Destination="1;440;0;1.00076;0;0.615268;0;0;1;0" Open="false"/>
   <Using Anchor to Position Instead of Stretch Destination="1;441;0;1.00076;0;0.727135;0;0;1;0" Open="false"/>
  </Adding Multiple Widgets>
  <Customizing Widgets with Classes Destination="1;442;0;1.00076;0;0.793651;0;0;1;0" Open="false">
   <Standardizing Behavior and Appearance Destination="1;443;0;1.00076;0;0.763416;0;0;1;0" Open="false">
    <Common behavior Destination="1;444;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Common appearance Destination="1;444;0;1.00076;0;0.606198;0;0;1;0" Open="false"/>
   </Standardizing Behavior and Appearance>
  </Customizing Widgets with Classes>
  <Reusable GUI Components with Classes Destination="1;445;0;1.00076;0;0.666667;0;0;1;0" Open="false">
   <Attaching Class Components Destination="1;447;0;1.00076;0;0.477702;0;0;1;0" Open="false"/>
   <Extending Class Components Destination="1;449;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
   <Standalone Container Classes Destination="1;450;0;1.00076;0;0.318972;0;0;1;0" Open="false"/>
  </Reusable GUI Components with Classes>
  <The End of the Tutorial Destination="1;452;0;1.00076;0;0.674225;0;0;1;0" Open="false"/>
  <Python/tkinter for Tcl/Tk Converts Destination="1;454;0;1.00076;0;0.335601;0;0;1;0" Open="false"/>
 </Chapter 7. Graphical User Interfaces>
 <Chapter 8. A tkinter Tour, Part 1 Destination="1;457;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Widgets and Gadgets and GUIs, Oh My!” Destination="1;457;0;1.00076;0;0.320484;0;0;1;0" Open="false">
   <This Chapter’s Topics Destination="1;457;0;1.00076;0;0.606198;0;0;1;0" Open="false"/>
  </“Widgets and Gadgets and GUIs, Oh My!”>
  <Configuring Widget Appearance Destination="1;458;0;1.00076;0;0.379441;0;0;1;0" Open="false"/>
  <Top-Level Windows Destination="1;461;0;1.00076;0;0.603175;0;0;1;0" Open="false">
   <Toplevel and Tk Widgets Destination="1;463;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Top-Level Window Protocols Destination="1;464;0;1.00076;0;0.137566;0;0;1;0" Open="false"/>
  </Top-Level Windows>
  <Dialogs Destination="1;468;0;1.00076;0;0.137566;0;0;1;0" Open="false">
   <Standard (Common) Dialogs Destination="1;468;0;1.00076;0;0.480726;0;0;1;0" Open="false">
    <A “smart” and reusable Quit button Destination="1;471;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
    <A dialog demo launcher bar Destination="1;472;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
    <Printing dialog results and passing callback data with lambdas Destination="1;476;0;1.00076;0;0.609221;0;0;1;0" Open="false"/>
    <Letting users select colors on the fly Destination="1;479;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Other standard dialog calls Destination="1;480;0;1.00076;0;0.184429;0;0;1;0" Open="false"/>
   </Standard (Common) Dialogs>
   <The Old-Style Dialog Module Destination="1;480;0;1.00076;0;0.377929;0;0;1;0" Open="false"/>
   <Custom Dialogs Destination="1;481;0;1.00076;0;0.544218;0;0;1;0" Open="false">
    <Making custom dialogs modal Destination="1;482;0;1.00076;0;0.772487;0;0;1;0" Open="false"/>
    <Other ways to be modal Destination="1;484;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Custom Dialogs>
  </Dialogs>
  <Binding Events Destination="1;485;0;1.00076;0;0.191988;0;0;1;0" Open="false">
   <Other bind Events Destination="1;489;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <More on <Destroy> events and the quit and destroy methods Destination="1;489;0;1.00076;0;0.805745;0;0;1;0" Open="false"/>
   </Other bind Events>
  </Binding Events>
  <Message and Entry Destination="1;490;0;1.00076;0;0.566893;0;0;1;0" Open="false">
   <Message Destination="1;490;0;1.00076;0;0.684807;0;0;1;0" Open="false"/>
   <Entry Destination="1;491;0;1.00076;0;0.380952;0;0;1;0" Open="false">
    <Programming Entry widgets Destination="1;492;0;1.00076;0;0.515495;0;0;1;0" Open="false"/>
   </Entry>
   <Laying Out Input Forms Destination="1;493;0;1.00076;0;0.3613;0;0;1;0" Open="false">
    <Going modal again Destination="1;494;0;1.00076;0;0.772487;0;0;1;0" Open="false"/>
   </Laying Out Input Forms>
   <tkinter “Variables” and Form Layout Alternatives Destination="1;496;0;1.00076;0;0.346183;0;0;1;0" Open="false"/>
  </Message and Entry>
  <Checkbutton, Radiobutton, and Scale Destination="1;499;0;1.00076;0;0.47619;0;0;1;0" Open="false">
   <Checkbuttons Destination="1;499;0;1.00076;0;0.668178;0;0;1;0" Open="false">
    <Check buttons and variables Destination="1;502;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Checkbuttons>
   <Radio Buttons Destination="1;504;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Radio buttons and variables Destination="1;505;0;1.00076;0;0.790627;0;0;1;0" Open="false"/>
    <Radio buttons without variables Destination="1;507;0;1.00076;0;0.191988;0;0;1;0" Open="false"/>
    <Hold onto your variables! Destination="1;508;0;1.00076;0;0.340136;0;0;1;0" Open="false"/>
   </Radio Buttons>
   <Scales (Sliders) Destination="1;509;0;1.00076;0;0.393046;0;0;1;0" Open="false">
    <Scales and variables Destination="1;511;0;1.00076;0;0.790627;0;0;1;0" Open="false"/>
   </Scales (Sliders)>
  </Checkbutton, Radiobutton, and Scale>
  <Running GUI Code Three Ways Destination="1;513;0;1.00076;0;0.367347;0;0;1;0" Open="false">
   <Attaching Frames Destination="1;513;0;1.00076;0;0.521542;0;0;1;0" Open="false">
    <Importing by name string Destination="1;515;0;1.00076;0;0.665155;0;0;1;0" Open="false"/>
    <Configuring at construction time Destination="1;516;0;1.00076;0;0.66062;0;0;1;0" Open="false"/>
   </Attaching Frames>
   <Independent Windows Destination="1;518;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Running Programs Destination="1;520;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Launching GUIs as programs other ways: multiprocessing Destination="1;521;0;1.00076;0;0.468632;0;0;1;0" Open="false"/>
    <Cross-program communication Destination="1;522;0;1.00076;0;0.743764;0;0;1;0" Open="false"/>
    <Coding for reusability Destination="1;524;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Running Programs>
  </Running GUI Code Three Ways>
  <Images Destination="1;526;0;1.00076;0;0.412698;0;0;1;0" Open="false">
   <Fun with Buttons and Pictures Destination="1;529;0;1.00076;0;0.633409;0;0;1;0" Open="false"/>
  </Images>
  <Viewing and Processing Images with PIL Destination="1;533;0;1.00076;0;0.190476;0;0;1;0" Open="false">
   <PIL Basics Destination="1;533;0;1.00076;0;0.545729;0;0;1;0" Open="false"/>
   <Displaying Other Image Types with PIL Destination="1;535;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Displaying all images in a directory Destination="1;537;0;1.00076;0;0.624339;0;0;1;0" Open="false"/>
   </Displaying Other Image Types with PIL>
   <Creating Image Thumbnails with PIL Destination="1;538;0;1.00076;0;0.630385;0;0;1;0" Open="false">
    <Performance: Saving thumbnail files Destination="1;542;0;1.00076;0;0.374906;0;0;1;0" Open="false"/>
    <Layout options: Gridding Destination="1;543;0;1.00076;0;0.356765;0;0;1;0" Open="false"/>
    <Layout options: Fixed-size buttons Destination="1;544;0;1.00076;0;0.640967;0;0;1;0" Open="false"/>
    <Scrolling and canvases (ahead) Destination="1;546;0;1.00076;0;0.754346;0;0;1;0" Open="false"/>
   </Creating Image Thumbnails with PIL>
  </Viewing and Processing Images with PIL>
 </Chapter 8. A tkinter Tour, Part 1>
 <Chapter 9. A tkinter Tour, Part 2 Destination="1;549;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“On Today’s Menu: Spam, Spam, and Spam” Destination="1;549;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <Menus Destination="1;549;0;1.00076;0;0.727135;0;0;1;0" Open="false">
   <Top-Level Window Menus Destination="1;550;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
   <Frame- and Menubutton-Based Menus Destination="1;554;0;1.00076;0;0.125472;0;0;1;0" Open="false">
    <Using Menubuttons and Optionmenus Destination="1;557;0;1.00076;0;0.386999;0;0;1;0" Open="false"/>
   </Frame- and Menubutton-Based Menus>
   <Windows with Both Menus and Toolbars Destination="1;559;0;1.00076;0;0.137566;0;0;1;0" Open="false">
    <Using images in toolbars, too Destination="1;562;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Automating menu construction Destination="1;563;0;1.00076;0;0.736206;0;0;1;0" Open="false"/>
   </Windows with Both Menus and Toolbars>
  </Menus>
  <Listboxes and Scrollbars Destination="1;564;0;1.00076;0;0.46712;0;0;1;0" Open="false">
   <Programming Listboxes Destination="1;566;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Programming Scroll Bars Destination="1;567;0;1.00076;0;0.603175;0;0;1;0" Open="false"/>
   <Packing Scroll Bars Destination="1;568;0;1.00076;0;0.763416;0;0;1;0" Open="false"/>
  </Listboxes and Scrollbars>
  <Text Destination="1;570;0;1.00076;0;0.119426;0;0;1;0" Open="false">
   <Programming the Text Widget Destination="1;572;0;1.00076;0;0.455026;0;0;1;0" Open="false">
    <Text is a Python string Destination="1;572;0;1.00076;0;0.639456;0;0;1;0" Open="false"/>
    <String positions Destination="1;573;0;1.00076;0;0.400605;0;0;1;0" Open="false">
     <Text indexes Destination="1;573;0;1.00076;0;0.583522;0;0;1;0" Open="false"/>
     <Text marks Destination="1;574;0;1.00076;0;0.263039;0;0;1;0" Open="false"/>
     <Text tags Destination="1;574;0;1.00076;0;0.545729;0;0;1;0" Open="false"/>
    </String positions>
   </Programming the Text Widget>
   <Adding Text-Editing Operations Destination="1;575;0;1.00076;0;0.672714;0;0;1;0" Open="false">
    <Using the clipboard Destination="1;578;0;1.00076;0;0.754346;0;0;1;0" Open="false"/>
    <Composition versus inheritance Destination="1;579;0;1.00076;0;0.489796;0;0;1;0" Open="false"/>
    <It’s called “Simple” for a reason: PyEdit (ahead) Destination="1;580;0;1.00076;0;0.386999;0;0;1;0" Open="false"/>
   </Adding Text-Editing Operations>
   <Unicode and the Text Widget Destination="1;580;0;1.00076;0;0.716553;0;0;1;0" Open="false">
    <String types in the Text widget Destination="1;581;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
    <Unicode text in strings Destination="1;582;0;1.00076;0;0.462585;0;0;1;0" Open="false"/>
    <Unicode text in files Destination="1;585;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Unicode and the Text widget Destination="1;585;0;1.00076;0;0.671202;0;0;1;0" Open="false"/>
    <The problem with treating text as bytes Destination="1;587;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
    <Other binary mode considerations Destination="1;588;0;1.00076;0;0.340136;0;0;1;0" Open="false"/>
    <Supporting Unicode in PyEdit (ahead) Destination="1;589;0;1.00076;0;0.633409;0;0;1;0" Open="false"/>
   </Unicode and the Text Widget>
   <Advanced Text and Tag Operations Destination="1;590;0;1.00076;0;0.25548;0;0;1;0" Open="false"/>
  </Text>
  <Canvas Destination="1;592;0;1.00076;0;0.137566;0;0;1;0" Open="false">
   <Basic Canvas Operations Destination="1;592;0;1.00076;0;0.328042;0;0;1;0" Open="false"/>
   <Programming the Canvas Widget Destination="1;593;0;1.00076;0;0.562358;0;0;1;0" Open="false">
    <Coordinates Destination="1;593;0;1.00076;0;0.672714;0;0;1;0" Open="false"/>
    <Object construction Destination="1;594;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
    <Object identifiers and operations Destination="1;595;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Canvas object tags Destination="1;595;0;1.00076;0;0.498866;0;0;1;0" Open="false"/>
   </Programming the Canvas Widget>
   <Scrolling Canvases Destination="1;596;0;1.00076;0;0.412698;0;0;1;0" Open="false"/>
   <Scrollable Canvases and Image Thumbnails Destination="1;599;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Scrolling images too: PyPhoto (ahead) Destination="1;602;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Scrollable Canvases and Image Thumbnails>
   <Using Canvas Events Destination="1;602;0;1.00076;0;0.474679;0;0;1;0" Open="false">
    <Binding events on specific items Destination="1;605;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Using Canvas Events>
  </Canvas>
  <Grids Destination="1;606;0;1.00076;0;0.347695;0;0;1;0" Open="false">
   <Why Grids? Destination="1;606;0;1.00076;0;0.739229;0;0;1;0" Open="false"/>
   <Grid Basics: Input Forms Revisited Destination="1;607;0;1.00076;0;0.273621;0;0;1;0" Open="false"/>
   <Comparing grid and pack Destination="1;608;0;1.00076;0;0.489796;0;0;1;0" Open="false"/>
   <Combining grid and pack Destination="1;610;0;1.00076;0;0.503401;0;0;1;0" Open="false"/>
   <Making Gridded Widgets Expandable Destination="1;612;0;1.00076;0;0.592593;0;0;1;0" Open="false">
    <Resizing in grids Destination="1;614;0;1.00076;0;0.500378;0;0;1;0" Open="false"/>
    <Spanning columns and rows Destination="1;615;0;1.00076;0;0.391534;0;0;1;0" Open="false"/>
   </Making Gridded Widgets Expandable>
   <Laying Out Larger Tables with grid Destination="1;616;0;1.00076;0;0.231293;0;0;1;0" Open="false"/>
  </Grids>
  <Time Tools, Threads, and Animation Destination="1;624;0;1.00076;0;0.199546;0;0;1;0" Open="false">
   <Using Threads with tkinter GUIs Destination="1;626;0;1.00076;0;0.312925;0;0;1;0" Open="false"/>
   <Using the after Method Destination="1;627;0;1.00076;0;0.585034;0;0;1;0" Open="false">
    <Hiding and redrawing widgets and windows Destination="1;629;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Using the after Method>
   <Simple Animation Techniques Destination="1;630;0;1.00076;0;0.542706;0;0;1;0" Open="false">
    <Using time.sleep loops Destination="1;631;0;1.00076;0;0.488284;0;0;1;0" Open="false"/>
    <Using widget.after events Destination="1;633;0;1.00076;0;0.444444;0;0;1;0" Open="false"/>
    <Using multiple time.sleep loop threads Destination="1;634;0;1.00076;0;0.594104;0;0;1;0" Open="false"/>
   </Simple Animation Techniques>
   <Other Animation Topics Destination="1;635;0;1.00076;0;0.671202;0;0;1;0" Open="false">
    <Other animation effects Destination="1;636;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Threads and animation Destination="1;636;0;1.00076;0;0.25548;0;0;1;0" Open="false"/>
    <Graphics and gaming toolkits Destination="1;636;0;1.00076;0;0.748299;0;0;1;0" Open="false"/>
   </Other Animation Topics>
  </Time Tools, Threads, and Animation>
  <The End of the Tour Destination="1;637;0;1.00076;0;0.293273;0;0;1;0" Open="false">
   <Other Widgets and Options Destination="1;637;0;1.00076;0;0.465608;0;0;1;0" Open="false"/>
  </The End of the Tour>
 </Chapter 9. A tkinter Tour, Part 2>
 <Chapter 10. GUI Coding Techniques Destination="1;639;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Building a Better Mousetrap” Destination="1;639;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <GuiMixin: Common Tool Mixin Classes Destination="1;640;0;1.00076;0;0.273621;0;0;1;0" Open="false">
   <Widget Builder Functions Destination="1;640;0;1.00076;0;0.429327;0;0;1;0" Open="false"/>
   <Mixin Utility Classes Destination="1;641;0;1.00076;0;0.654573;0;0;1;0" Open="false"/>
  </GuiMixin: Common Tool Mixin Classes>
  <GuiMaker: Automating Menus and Toolbars Destination="1;645;0;1.00076;0;0.374906;0;0;1;0" Open="false">
   <Subclass Protocols Destination="1;649;0;1.00076;0;0.201058;0;0;1;0" Open="false"/>
   <GuiMaker Classes Destination="1;650;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <GuiMaker Self-Test Destination="1;650;0;1.00076;0;0.450491;0;0;1;0" Open="false"/>
   <BigGui: A Client Demo Program Destination="1;651;0;1.00076;0;0.517007;0;0;1;0" Open="false"/>
  </GuiMaker: Automating Menus and Toolbars>
  <ShellGui: GUIs for Command-Line Tools Destination="1;655;0;1.00076;0;0.207105;0;0;1;0" Open="false">
   <A Generic Shell-Tools Display Destination="1;655;0;1.00076;0;0.480726;0;0;1;0" Open="false"/>
   <Application-Specific Tool Set Classes Destination="1;657;0;1.00076;0;0.40514;0;0;1;0" Open="false"/>
   <Adding GUI Frontends to Command Lines Destination="1;659;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Non-GUI scripts Destination="1;659;0;1.00076;0;0.187453;0;0;1;0" Open="false"/>
    <GUI input dialogs Destination="1;661;0;1.00076;0;0.284203;0;0;1;0" Open="false"/>
    <Room for improvement Destination="1;664;0;1.00076;0;0.44898;0;0;1;0" Open="false"/>
   </Adding GUI Frontends to Command Lines>
  </ShellGui: GUIs for Command-Line Tools>
  <GuiStreams: Redirecting Streams to Widgets Destination="1;665;0;1.00076;0;0.325019;0;0;1;0" Open="false">
   <Using Redirection for the Packing Scripts Destination="1;669;0;1.00076;0;0.374906;0;0;1;0" Open="false"/>
  </GuiStreams: Redirecting Streams to Widgets>
  <Reloading Callback Handlers Dynamically Destination="1;670;0;1.00076;0;0.424792;0;0;1;0" Open="false"/>
  <Wrapping Up Top-Level Window Interfaces Destination="1;672;0;1.00076;0;0.515495;0;0;1;0" Open="false"/>
  <GUIs, Threads, and Queues Destination="1;677;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <Placing Data on Queues Destination="1;678;0;1.00076;0;0.597128;0;0;1;0" Open="false">
    <Recoding with classes and bound methods Destination="1;680;0;1.00076;0;0.468632;0;0;1;0" Open="false"/>
    <Thread exits in GUIs Destination="1;681;0;1.00076;0;0.539683;0;0;1;0" Open="false"/>
   </Placing Data on Queues>
   <Placing Callbacks on Queues Destination="1;682;0;1.00076;0;0.119426;0;0;1;0" Open="false">
    <Passing bound method callbacks on queues Destination="1;686;0;1.00076;0;0.696901;0;0;1;0" Open="false"/>
   </Placing Callbacks on Queues>
  </GUIs, Threads, and Queues>
  <More Ways to Add GUIs to Non-GUI Code Destination="1;688;0;1.00076;0;0.725624;0;0;1;0" Open="false">
   <Popping Up GUI Windows on Demand Destination="1;689;0;1.00076;0;0.46712;0;0;1;0" Open="false"/>
   <Adding a GUI As a Separate Program: Sockets (A Second Look) Destination="1;691;0;1.00076;0;0.739229;0;0;1;0" Open="false"/>
   <Adding a GUI As a Separate Program: Command Pipes Destination="1;696;0;1.00076;0;0.353741;0;0;1;0" Open="false">
    <The specter of blocking input calls Destination="1;698;0;1.00076;0;0.663643;0;0;1;0" Open="false"/>
    <Updating GUIs within threads…and other nonsolutions Destination="1;699;0;1.00076;0;0.281179;0;0;1;0" Open="false"/>
    <Avoiding blocking input calls with non-GUI threads Destination="1;700;0;1.00076;0;0.263039;0;0;1;0" Open="false"/>
    <Sockets and pipes: Compare and contrast Destination="1;701;0;1.00076;0;0.686319;0;0;1;0" Open="false"/>
    <Other uses for threaded pipe GUIs Destination="1;702;0;1.00076;0;0.474679;0;0;1;0" Open="false"/>
   </Adding a GUI As a Separate Program: Command Pipes>
  </More Ways to Add GUIs to Non-GUI Code>
  <The PyDemos and PyGadgets Launchers Destination="1;704;0;1.00076;0;0.119426;0;0;1;0" Open="false">
   <PyDemos Launcher Bar (Mostly External) Destination="1;704;0;1.00076;0;0.686319;0;0;1;0" Open="false"/>
   <PyGadgets Launcher Bar Destination="1;709;0;1.00076;0;0.675737;0;0;1;0" Open="false"/>
  </The PyDemos and PyGadgets Launchers>
 </Chapter 10. GUI Coding Techniques>
 <Chapter 11. Complete GUI Programs Destination="1;713;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Python, Open Source, and Camaros” Destination="1;713;0;1.00076;0;0.320484;0;0;1;0" Open="false">
   <Examples in Other Chapters Destination="1;714;0;1.00076;0;0.293273;0;0;1;0" Open="false"/>
   <This Chapter’s Strategy Destination="1;715;0;1.00076;0;0.181406;0;0;1;0" Open="false"/>
  </“Python, Open Source, and Camaros”>
  <PyEdit: A Text Editor Program/Object Destination="1;716;0;1.00076;0;0.680272;0;0;1;0" Open="false">
   <Running PyEdit Destination="1;717;0;1.00076;0;0.689342;0;0;1;0" Open="false">
    <Menus and toolbars Destination="1;718;0;1.00076;0;0.631897;0;0;1;0" Open="false"/>
    <Dialogs Destination="1;719;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Running program code Destination="1;719;0;1.00076;0;0.754346;0;0;1;0" Open="false"/>
    <Multiple windows Destination="1;720;0;1.00076;0;0.432351;0;0;1;0" Open="false"/>
    <Other PyEdit examples and screenshots in this book Destination="1;724;0;1.00076;0;0.477702;0;0;1;0" Open="false"/>
   </Running PyEdit>
   <PyEdit Changes in Version 2.0 (Third Edition) Destination="1;724;0;1.00076;0;0.715042;0;0;1;0" Open="false">
    <Font dialog Destination="1;725;0;1.00076;0;0.261527;0;0;1;0" Open="false"/>
    <Undo, redo, and modified tests Destination="1;725;0;1.00076;0;0.417234;0;0;1;0" Open="false"/>
    <Configuration module Destination="1;725;0;1.00076;0;0.692366;0;0;1;0" Open="false"/>
   </PyEdit Changes in Version 2.0 (Third Edition)>
   <PyEdit Changes in Version 2.1 (Fourth Edition) Destination="1;726;0;1.00076;0;0.119426;0;0;1;0" Open="false">
    <Modal dialog state fix Destination="1;726;0;1.00076;0;0.643991;0;0;1;0" Open="false"/>
    <Cross-process change tests on Quit Destination="1;727;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
    <New Grep dialog: Threaded and Unicode-aware file tree search Destination="1;727;0;1.00076;0;0.430839;0;0;1;0" Open="false">
     <Grep threading model Destination="1;727;0;1.00076;0;0.752834;0;0;1;0" Open="false"/>
     <Grep Unicode model Destination="1;728;0;1.00076;0;0.273621;0;0;1;0" Open="false"/>
    </New Grep dialog: Threaded and Unicode-aware file tree search>
    <Update for initial positioning Destination="1;729;0;1.00076;0;0.311413;0;0;1;0" Open="false"/>
    <Improvements for running code Destination="1;729;0;1.00076;0;0.696901;0;0;1;0" Open="false"/>
    <Unicode (Internationalized) text support Destination="1;730;0;1.00076;0;0.452003;0;0;1;0" Open="false">
     <Unicode file and display model Destination="1;730;0;1.00076;0;0.831444;0;0;1;0" Open="false"/>
     <Unicode options and choices Destination="1;732;0;1.00076;0;0.740741;0;0;1;0" Open="false"/>
    </Unicode (Internationalized) text support>
    <More on Quit checks: The <Destroy> event revisited Destination="1;734;0;1.00076;0;0.517007;0;0;1;0" Open="false"/>
   </PyEdit Changes in Version 2.1 (Fourth Edition)>
   <PyEdit Source Code Destination="1;735;0;1.00076;0;0.787604;0;0;1;0" Open="false">
    <User configurations file Destination="1;736;0;1.00076;0;0.273621;0;0;1;0" Open="false"/>
    <Windows (and other) launch files Destination="1;737;0;1.00076;0;0.589569;0;0;1;0" Open="false"/>
    <Main implementation file Destination="1;738;0;1.00076;0;0.67876;0;0;1;0" Open="false"/>
   </PyEdit Source Code>
  </PyEdit: A Text Editor Program/Object>
  <PyPhoto: An Image Viewer and Resizer Destination="1;758;0;1.00076;0;0.705971;0;0;1;0" Open="false">
   <Running PyPhoto Destination="1;759;0;1.00076;0;0.400605;0;0;1;0" Open="false"/>
   <PyPhoto Source Code Destination="1;761;0;1.00076;0;0.686319;0;0;1;0" Open="false"/>
  </PyPhoto: An Image Viewer and Resizer>
  <PyView: An Image and Notes Slideshow Destination="1;769;0;1.00076;0;0.459562;0;0;1;0" Open="false">
   <Running PyView Destination="1;769;0;1.00076;0;0.613757;0;0;1;0" Open="false">
    <Embedding PyEdit in PyView Destination="1;771;0;1.00076;0;0.687831;0;0;1;0" Open="false"/>
   </Running PyView>
   <PyView Source Code Destination="1;774;0;1.00076;0;0.311413;0;0;1;0" Open="false"/>
  </PyView: An Image and Notes Slideshow>
  <PyDraw: Painting and Moving Graphics Destination="1;780;0;1.00076;0;0.119426;0;0;1;0" Open="false">
   <Running PyDraw Destination="1;780;0;1.00076;0;0.309902;0;0;1;0" Open="false"/>
   <PyDraw Source Code Destination="1;780;0;1.00076;0;0.739229;0;0;1;0" Open="false"/>
  </PyDraw: Painting and Moving Graphics>
  <PyClock: An Analog/Digital Clock Widget Destination="1;789;0;1.00076;0;0.110355;0;0;1;0" Open="false">
   <A Quick Geometry Lesson Destination="1;789;0;1.00076;0;0.338624;0;0;1;0" Open="false"/>
   <Running PyClock Destination="1;793;0;1.00076;0;0.403628;0;0;1;0" Open="false"/>
   <PyClock Source Code Destination="1;796;0;1.00076;0;0.681784;0;0;1;0" Open="false"/>
  </PyClock: An Analog/Digital Clock Widget>
  <PyToe: A Tic-Tac-Toe Game Widget Destination="1;804;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <Running PyToe Destination="1;804;0;1.00076;0;0.412698;0;0;1;0" Open="false"/>
   <PyToe Source Code (External) Destination="1;805;0;1.00076;0;0.56387;0;0;1;0" Open="false"/>
  </PyToe: A Tic-Tac-Toe Game Widget>
  <Where to Go from Here Destination="1;808;0;1.00076;0;0.749811;0;0;1;0" Open="false"/>
 </Chapter 11. Complete GUI Programs>
</Part III. GUI Programming>
<Part IV. Internet Programming Destination="1;811;0;1.00076;0;0.0786092;0;0;1;0" Open="false">
 <Chapter 12. Network Scripting Destination="1;813;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Tune In, Log On, and Drop Out” Destination="1;813;0;1.00076;0;0.320484;0;0;1;0" Open="false">
   <Internet Scripting Topics Destination="1;814;0;1.00076;0;0.44898;0;0;1;0" Open="false">
    <What we will cover Destination="1;815;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
    <What we won’t cover Destination="1;816;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
    <Other themes in this part of the book Destination="1;816;0;1.00076;0;0.568405;0;0;1;0" Open="false"/>
   </Internet Scripting Topics>
   <Running Examples in This Part of the Book Destination="1;817;0;1.00076;0;0.429327;0;0;1;0" Open="false"/>
  </“Tune In, Log On, and Drop Out”>
  <Python Internet Development Options Destination="1;819;0;1.00076;0;0.226757;0;0;1;0" Open="false"/>
  <Plumbing the Internet Destination="1;822;0;1.00076;0;0.610733;0;0;1;0" Open="false">
   <The Socket Layer Destination="1;823;0;1.00076;0;0.119426;0;0;1;0" Open="false">
    <Machine identifiers Destination="1;823;0;1.00076;0;0.539683;0;0;1;0" Open="false"/>
   </The Socket Layer>
   <The Protocol Layer Destination="1;824;0;1.00076;0;0.721088;0;0;1;0" Open="false">
    <Port number rules Destination="1;825;0;1.00076;0;0.30839;0;0;1;0" Open="false"/>
    <Clients and servers Destination="1;825;0;1.00076;0;0.748299;0;0;1;0" Open="false"/>
    <Protocol structures Destination="1;826;0;1.00076;0;0.737717;0;0;1;0" Open="false"/>
   </The Protocol Layer>
   <Python’s Internet Library Modules Destination="1;827;0;1.00076;0;0.311413;0;0;1;0" Open="false"/>
  </Plumbing the Internet>
  <Socket Programming Destination="1;829;0;1.00076;0;0.300831;0;0;1;0" Open="false">
   <Socket Basics Destination="1;830;0;1.00076;0;0.513983;0;0;1;0" Open="false">
    <Server socket calls Destination="1;832;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Transferring byte strings and objects Destination="1;833;0;1.00076;0;0.663643;0;0;1;0" Open="false"/>
    <Client socket calls Destination="1;834;0;1.00076;0;0.758881;0;0;1;0" Open="false"/>
   </Socket Basics>
   <Running Socket Programs Locally Destination="1;836;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Running Socket Programs Remotely Destination="1;837;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Socket pragmatics Destination="1;838;0;1.00076;0;0.675737;0;0;1;0" Open="false"/>
   </Running Socket Programs Remotely>
   <Spawning Clients in Parallel Destination="1;840;0;1.00076;0;0.482237;0;0;1;0" Open="false">
    <Preview: Denied client connections Destination="1;841;0;1.00076;0;0.659108;0;0;1;0" Open="false"/>
   </Spawning Clients in Parallel>
   <Talking to Reserved Ports Destination="1;843;0;1.00076;0;0.25548;0;0;1;0" Open="false">
    <Binding reserved port servers Destination="1;844;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
   </Talking to Reserved Ports>
  </Socket Programming>
  <Handling Multiple Clients Destination="1;844;0;1.00076;0;0.62585;0;0;1;0" Open="false">
   <Forking Servers Destination="1;845;0;1.00076;0;0.273621;0;0;1;0" Open="false">
    <Running the forking server Destination="1;846;0;1.00076;0;0.343159;0;0;1;0" Open="false"/>
    <Other run modes: Local servers with Cygwin and remote clients Destination="1;848;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
    <Forked processes and sockets Destination="1;849;0;1.00076;0;0.204082;0;0;1;0" Open="false"/>
    <Exiting from children Destination="1;849;0;1.00076;0;0.397581;0;0;1;0" Open="false"/>
    <Killing the zombies: Don’t fear the reaper! Destination="1;849;0;1.00076;0;0.654573;0;0;1;0" Open="false"/>
    <Preventing zombies with signal handlers on Linux Destination="1;851;0;1.00076;0;0.462585;0;0;1;0" Open="false"/>
    <Why multiprocessing doesn’t help with socket server portability Destination="1;855;0;1.00076;0;0.512472;0;0;1;0" Open="false"/>
   </Forking Servers>
   <Threading Servers Destination="1;857;0;1.00076;0;0.506425;0;0;1;0" Open="false"/>
   <Standard Library Server Classes Destination="1;860;0;1.00076;0;0.284203;0;0;1;0" Open="false"/>
   <Multiplexing Servers with select Destination="1;862;0;1.00076;0;0.119426;0;0;1;0" Open="false">
    <A select-based echo server Destination="1;863;0;1.00076;0;0.293273;0;0;1;0" Open="false"/>
    <Running the select server Destination="1;865;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Multiplexing Servers with select>
   <Summary: Choosing a Server Scheme Destination="1;868;0;1.00076;0;0.30839;0;0;1;0" Open="false"/>
  </Handling Multiple Clients>
  <Making Sockets Look Like Files and Streams Destination="1;869;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <A Stream Redirection Utility Destination="1;870;0;1.00076;0;0.237339;0;0;1;0" Open="false">
    <Text-mode files and buffered output streams Destination="1;874;0;1.00076;0;0.719577;0;0;1;0" Open="false"/>
    <Stream requirements Destination="1;876;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
    <Line buffering Destination="1;877;0;1.00076;0;0.491308;0;0;1;0" Open="false"/>
    <Solutions Destination="1;879;0;1.00076;0;0.263039;0;0;1;0" Open="false"/>
    <Buffering in other contexts: Command pipes revisited Destination="1;880;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
    <Sockets versus command pipes Destination="1;881;0;1.00076;0;0.252457;0;0;1;0" Open="false"/>
   </A Stream Redirection Utility>
  </Making Sockets Look Like Files and Streams>
  <A Simple Python File Server Destination="1;882;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <Running the File Server and Clients Destination="1;884;0;1.00076;0;0.220711;0;0;1;0" Open="false"/>
   <Adding a User-Interface Frontend Destination="1;885;0;1.00076;0;0.303855;0;0;1;0" Open="false">
    <Using row frames and command lines Destination="1;885;0;1.00076;0;0.606198;0;0;1;0" Open="false"/>
    <Using grids and function calls Destination="1;887;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
    <Using a reusable form-layout class Destination="1;888;0;1.00076;0;0.486772;0;0;1;0" Open="false"/>
   </Adding a User-Interface Frontend>
  </A Simple Python File Server>
 </Chapter 12. Network Scripting>
 <Chapter 13. Client-Side Scripting Destination="1;895;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Socket to Me!” Destination="1;895;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <FTP: Transferring Files over the Net Destination="1;896;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
  <Transferring Files with ftplib Destination="1;896;0;1.00076;0;0.603175;0;0;1;0" Open="false">
   <Using urllib to Download Files Destination="1;899;0;1.00076;0;0.698413;0;0;1;0" Open="false"/>
   <FTP get and put Utilities Destination="1;902;0;1.00076;0;0.21164;0;0;1;0" Open="false">
    <Download utility Destination="1;903;0;1.00076;0;0.321995;0;0;1;0" Open="false"/>
    <Upload utility Destination="1;906;0;1.00076;0;0.356765;0;0;1;0" Open="false"/>
    <Playing the Monty Python theme song Destination="1;907;0;1.00076;0;0.553288;0;0;1;0" Open="false"/>
   </FTP get and put Utilities>
   <Adding a User Interface Destination="1;909;0;1.00076;0;0.272109;0;0;1;0" Open="false"/>
  </Transferring Files with ftplib>
  <Transferring Directories with ftplib Destination="1;916;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <Downloading Site Directories Destination="1;916;0;1.00076;0;0.504913;0;0;1;0" Open="false"/>
   <Uploading Site Directories Destination="1;922;0;1.00076;0;0.408163;0;0;1;0" Open="false"/>
   <Refactoring Uploads and Downloads for Reuse Destination="1;926;0;1.00076;0;0.270597;0;0;1;0" Open="false">
    <Refactoring with functions Destination="1;926;0;1.00076;0;0.654573;0;0;1;0" Open="false"/>
    <Refactoring with classes Destination="1;930;0;1.00076;0;0.548753;0;0;1;0" Open="false"/>
   </Refactoring Uploads and Downloads for Reuse>
  </Transferring Directories with ftplib>
  <Transferring Directory Trees with ftplib Destination="1;934;0;1.00076;0;0.749811;0;0;1;0" Open="false">
   <Uploading Local Trees Destination="1;935;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
   <Deleting Remote Trees Destination="1;937;0;1.00076;0;0.715042;0;0;1;0" Open="false"/>
   <Downloading Remote Trees Destination="1;941;0;1.00076;0;0.284203;0;0;1;0" Open="false"/>
  </Transferring Directory Trees with ftplib>
  <Processing Internet Email Destination="1;941;0;1.00076;0;0.568405;0;0;1;0" Open="false">
   <Unicode in Python 3.X and Email Tools Destination="1;942;0;1.00076;0;0.347695;0;0;1;0" Open="false"/>
  </Processing Internet Email>
  <POP: Fetching Email Destination="1;943;0;1.00076;0;0.740741;0;0;1;0" Open="false">
   <Mail Configuration Module Destination="1;944;0;1.00076;0;0.748299;0;0;1;0" Open="false"/>
   <POP Mail Reader Script Destination="1;947;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Fetching Messages Destination="1;948;0;1.00076;0;0.73167;0;0;1;0" Open="false"/>
   <Fetching Email at the Interactive Prompt Destination="1;951;0;1.00076;0;0.185941;0;0;1;0" Open="false"/>
  </POP: Fetching Email>
  <SMTP: Sending Email Destination="1;952;0;1.00076;0;0.433862;0;0;1;0" Open="false">
   <SMTP Mail Sender Script Destination="1;953;0;1.00076;0;0.556311;0;0;1;0" Open="false"/>
   <Sending Messages Destination="1;955;0;1.00076;0;0.66969;0;0;1;0" Open="false">
    <Verifying receipt Destination="1;957;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Manipulating both From and To Destination="1;958;0;1.00076;0;0.383976;0;0;1;0" Open="false"/>
   </Sending Messages>
   <Sending Email at the Interactive Prompt Destination="1;961;0;1.00076;0;0.752834;0;0;1;0" Open="false"/>
  </SMTP: Sending Email>
  <email: Parsing and Composing Mail Content Destination="1;963;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <Message Objects Destination="1;964;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
   <Basic email Package Interfaces in Action Destination="1;966;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Handling multipart messages Destination="1;967;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Basic email Package Interfaces in Action>
   <Unicode, Internationalization, and the Python 3.1 email Package Destination="1;968;0;1.00076;0;0.591081;0;0;1;0" Open="false">
    <Parser decoding requirement Destination="1;969;0;1.00076;0;0.748299;0;0;1;0" Open="false"/>
    <Text payload encodings: Handling mixed type results Destination="1;971;0;1.00076;0;0.773998;0;0;1;0" Open="false"/>
    <Text payload encodings: Using header information to decode Destination="1;973;0;1.00076;0;0.575964;0;0;1;0" Open="false"/>
    <Message header encodings: email package support Destination="1;975;0;1.00076;0;0.736206;0;0;1;0" Open="false"/>
    <Message address header encodings and parsing, and header creation Destination="1;977;0;1.00076;0;0.418745;0;0;1;0" Open="false"/>
    <Workaround: Message text generation for binary attachment payloads is broken Destination="1;980;0;1.00076;0;0.21164;0;0;1;0" Open="false"/>
    <Workaround: Message composition for non-ASCII text parts is broken Destination="1;983;0;1.00076;0;0.657596;0;0;1;0" Open="false"/>
    <Summary: Solutions and workarounds Destination="1;988;0;1.00076;0;0.671202;0;0;1;0" Open="false"/>
   </Unicode, Internationalization, and the Python 3.1 email Package>
  </email: Parsing and Composing Mail Content>
  <A Console-Based Email Client Destination="1;989;0;1.00076;0;0.687831;0;0;1;0" Open="false">
   <Running the pymail Console Client Destination="1;994;0;1.00076;0;0.594104;0;0;1;0" Open="false"/>
  </A Console-Based Email Client>
  <The mailtools Utility Package Destination="1;998;0;1.00076;0;0.436886;0;0;1;0" Open="false">
   <Initialization File Destination="1;999;0;1.00076;0;0.631897;0;0;1;0" Open="false"/>
   <MailTool Class Destination="1;1000;0;1.00076;0;0.643991;0;0;1;0" Open="false"/>
   <MailSender Class Destination="1;1001;0;1.00076;0;0.296296;0;0;1;0" Open="false">
    <Unicode issues for attachments, save files, and headers Destination="1;1001;0;1.00076;0;0.517007;0;0;1;0" Open="false"/>
   </MailSender Class>
   <MailFetcher Class Destination="1;1009;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <General usage Destination="1;1009;0;1.00076;0;0.169312;0;0;1;0" Open="false"/>
    <Unicode decoding for full mail text on fetches Destination="1;1009;0;1.00076;0;0.544218;0;0;1;0" Open="false"/>
    <Inbox synchronization tools Destination="1;1010;0;1.00076;0;0.521542;0;0;1;0" Open="false"/>
   </MailFetcher Class>
   <MailParser Class Destination="1;1018;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Unicode decoding for text part payloads and message headers Destination="1;1018;0;1.00076;0;0.279667;0;0;1;0" Open="false"/>
   </MailParser Class>
   <Self-Test Script Destination="1;1025;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Running the self-test Destination="1;1026;0;1.00076;0;0.314437;0;0;1;0" Open="false"/>
   </Self-Test Script>
   <Updating the pymail Console Client Destination="1;1028;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Running the pymail2 console client Destination="1;1031;0;1.00076;0;0.125472;0;0;1;0" Open="false"/>
   </Updating the pymail Console Client>
  </The mailtools Utility Package>
  <NNTP: Accessing Newsgroups Destination="1;1033;0;1.00076;0;0.761905;0;0;1;0" Open="false"/>
  <HTTP: Accessing Websites Destination="1;1036;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  <The urllib Package Revisited Destination="1;1039;0;1.00076;0;0.256992;0;0;1;0" Open="false">
   <Other urllib Interfaces Destination="1;1041;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Invoking programs and escaping text Destination="1;1042;0;1.00076;0;0.787604;0;0;1;0" Open="false"/>
   </Other urllib Interfaces>
  </The urllib Package Revisited>
  <Other Client-Side Scripting Options Destination="1;1044;0;1.00076;0;0.456538;0;0;1;0" Open="false"/>
 </Chapter 13. Client-Side Scripting>
 <Chapter 14. The PyMailGUI Client Destination="1;1047;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Use the Source, Luke” Destination="1;1047;0;1.00076;0;0.320484;0;0;1;0" Open="false">
   <Source Code Modules and Size Destination="1;1048;0;1.00076;0;0.21164;0;0;1;0" Open="false">
    <Code size Destination="1;1049;0;1.00076;0;0.41421;0;0;1;0" Open="false"/>
    <Code Structure Destination="1;1050;0;1.00076;0;0.25548;0;0;1;0" Open="false"/>
   </Source Code Modules and Size>
   <Why PyMailGUI? Destination="1;1050;0;1.00076;0;0.745276;0;0;1;0" Open="false"/>
   <Running PyMailGUI Destination="1;1052;0;1.00076;0;0.275132;0;0;1;0" Open="false"/>
   <Presentation Strategy Destination="1;1052;0;1.00076;0;0.640967;0;0;1;0" Open="false"/>
  </“Use the Source, Luke”>
  <Major PyMailGUI Changes Destination="1;1053;0;1.00076;0;0.462585;0;0;1;0" Open="false">
   <New in Version 2.1 and 2.0 (Third Edition) Destination="1;1053;0;1.00076;0;0.598639;0;0;1;0" Open="false"/>
   <New in Version 3.0 (Fourth Edition) Destination="1;1054;0;1.00076;0;0.781557;0;0;1;0" Open="false">
    <Version 3.0 Unicode support policies Destination="1;1059;0;1.00076;0;0.326531;0;0;1;0" Open="false"/>
   </New in Version 3.0 (Fourth Edition)>
  </Major PyMailGUI Changes>
  <A PyMailGUI Demo Destination="1;1061;0;1.00076;0;0.622827;0;0;1;0" Open="false">
   <Getting Started Destination="1;1062;0;1.00076;0;0.329554;0;0;1;0" Open="false"/>
   <Loading Mail Destination="1;1067;0;1.00076;0;0.795163;0;0;1;0" Open="false"/>
   <Threading Model Destination="1;1069;0;1.00076;0;0.560847;0;0;1;0" Open="false">
    <Threading model implementation Destination="1;1071;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Threading Model>
   <Load Server Interface Destination="1;1072;0;1.00076;0;0.261527;0;0;1;0" Open="false"/>
   <Offline Processing with Save and Open Destination="1;1073;0;1.00076;0;0.727135;0;0;1;0" Open="false"/>
   <Sending Email and Attachments Destination="1;1075;0;1.00076;0;0.689342;0;0;1;0" Open="false"/>
   <Viewing Email and Attachments Destination="1;1079;0;1.00076;0;0.21164;0;0;1;0" Open="false"/>
   <Email Replies and Forwards and Recipient Options Destination="1;1085;0;1.00076;0;0.761905;0;0;1;0" Open="false"/>
   <Deleting Email Destination="1;1091;0;1.00076;0;0.529101;0;0;1;0" Open="false"/>
   <POP Message Numbers and Synchronization Destination="1;1093;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
   <Handling HTML Content in Email Destination="1;1095;0;1.00076;0;0.191988;0;0;1;0" Open="false"/>
   <Mail Content Internationalization Support Destination="1;1097;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
   <Alternative Configurations and Accounts Destination="1;1101;0;1.00076;0;0.553288;0;0;1;0" Open="false"/>
   <Multiple Windows and Status Messages Destination="1;1102;0;1.00076;0;0.480726;0;0;1;0" Open="false"/>
  </A PyMailGUI Demo>
  <PyMailGUI Implementation Destination="1;1104;0;1.00076;0;0.386999;0;0;1;0" Open="false">
   <PyMailGUI: The Main Module Destination="1;1105;0;1.00076;0;0.699924;0;0;1;0" Open="false"/>
   <SharedNames: Program-Wide Globals Destination="1;1108;0;1.00076;0;0.400605;0;0;1;0" Open="false"/>
   <ListWindows: Message List Windows Destination="1;1109;0;1.00076;0;0.763416;0;0;1;0" Open="false"/>
   <ViewWindows: Message View Windows Destination="1;1127;0;1.00076;0;0.415722;0;0;1;0" Open="false"/>
   <messagecache: Message Cache Manager Destination="1;1137;0;1.00076;0;0.545729;0;0;1;0" Open="false"/>
   <popuputil: General-Purpose GUI Pop Ups Destination="1;1140;0;1.00076;0;0.690854;0;0;1;0" Open="false"/>
   <wraplines: Line Split Tools Destination="1;1142;0;1.00076;0;0.589569;0;0;1;0" Open="false"/>
   <html2text: Extracting Text from HTML (Prototype, Preview) Destination="1;1144;0;1.00076;0;0.748299;0;0;1;0" Open="false"/>
   <mailconfig: User Configurations Destination="1;1147;0;1.00076;0;0.696901;0;0;1;0" Open="false"/>
   <textConfig: Customizing Pop-Up PyEdit Windows Destination="1;1152;0;1.00076;0;0.517007;0;0;1;0" Open="false"/>
   <PyMailGUIHelp: User Help Text and Display Destination="1;1153;0;1.00076;0;0.139078;0;0;1;0" Open="false"/>
   <altconfigs: Configuring for Multiple Accounts Destination="1;1156;0;1.00076;0;0.182918;0;0;1;0" Open="false"/>
  </PyMailGUI Implementation>
  <Ideas for Improvement Destination="1;1158;0;1.00076;0;0.485261;0;0;1;0" Open="false"/>
 </Chapter 14. The PyMailGUI Client>
 <Chapter 15. Server-Side Scripting Destination="1;1167;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Oh, What a Tangled Web We Weave” Destination="1;1167;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <What’s a Server-Side CGI Script? Destination="1;1168;0;1.00076;0;0.338624;0;0;1;0" Open="false">
   <The Script Behind the Curtain Destination="1;1168;0;1.00076;0;0.78458;0;0;1;0" Open="false"/>
   <Writing CGI Scripts in Python Destination="1;1170;0;1.00076;0;0.600151;0;0;1;0" Open="false"/>
  </What’s a Server-Side CGI Script?>
  <Running Server-Side Examples Destination="1;1172;0;1.00076;0;0.137566;0;0;1;0" Open="false">
   <Web Server Options Destination="1;1172;0;1.00076;0;0.436886;0;0;1;0" Open="false"/>
   <Running a Local Web Server Destination="1;1173;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
   <The Server-Side Examples Root Page Destination="1;1175;0;1.00076;0;0.191988;0;0;1;0" Open="false"/>
   <Viewing Server-Side Examples and Output Destination="1;1176;0;1.00076;0;0.293273;0;0;1;0" Open="false"/>
  </Running Server-Side Examples>
  <Climbing the CGI Learning Curve Destination="1;1177;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <A First Web Page Destination="1;1177;0;1.00076;0;0.293273;0;0;1;0" Open="false">
    <HTML basics Destination="1;1178;0;1.00076;0;0.417234;0;0;1;0" Open="false"/>
    <Internet addresses (URLs) Destination="1;1179;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Using minimal URLs Destination="1;1181;0;1.00076;0;0.45805;0;0;1;0" Open="false"/>
    <HTML file permission constraints Destination="1;1182;0;1.00076;0;0.553288;0;0;1;0" Open="false"/>
   </A First Web Page>
   <A First CGI Script Destination="1;1183;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Installing CGI scripts Destination="1;1184;0;1.00076;0;0.523054;0;0;1;0" Open="false"/>
    <Finding Python on remote servers Destination="1;1187;0;1.00076;0;0.252457;0;0;1;0" Open="false"/>
   </A First CGI Script>
   <Adding Pictures and Generating Tables Destination="1;1188;0;1.00076;0;0.25548;0;0;1;0" Open="false">
    <Table tags Destination="1;1190;0;1.00076;0;0.648526;0;0;1;0" Open="false"/>
   </Adding Pictures and Generating Tables>
   <Adding User Interaction Destination="1;1191;0;1.00076;0;0.364324;0;0;1;0" Open="false">
    <Submission page Destination="1;1191;0;1.00076;0;0.51096;0;0;1;0" Open="false"/>
    <More on form tags Destination="1;1192;0;1.00076;0;0.47619;0;0;1;0" Open="false"/>
    <Response script Destination="1;1194;0;1.00076;0;0.199546;0;0;1;0" Open="false"/>
    <Passing parameters in URLs Destination="1;1195;0;1.00076;0;0.754346;0;0;1;0" Open="false"/>
    <Testing outside browsers with the module urllib.request Destination="1;1197;0;1.00076;0;0.790627;0;0;1;0" Open="false"/>
   </Adding User Interaction>
   <Using Tables to Lay Out Forms Destination="1;1199;0;1.00076;0;0.657596;0;0;1;0" Open="false">
    <Converting strings in CGI scripts Destination="1;1203;0;1.00076;0;0.137566;0;0;1;0" Open="false"/>
    <Debugging CGI scripts Destination="1;1203;0;1.00076;0;0.606198;0;0;1;0" Open="false"/>
   </Using Tables to Lay Out Forms>
   <Adding Common Input Devices Destination="1;1205;0;1.00076;0;0.40514;0;0;1;0" Open="false"/>
   <Changing Input Layouts Destination="1;1208;0;1.00076;0;0.541194;0;0;1;0" Open="false">
    <Keeping display and logic separate Destination="1;1211;0;1.00076;0;0.497354;0;0;1;0" Open="false"/>
   </Changing Input Layouts>
   <Passing Parameters in Hardcoded URLs Destination="1;1212;0;1.00076;0;0.137566;0;0;1;0" Open="false"/>
   <Passing Parameters in Hidden Form Fields Destination="1;1214;0;1.00076;0;0.574452;0;0;1;0" Open="false"/>
  </Climbing the CGI Learning Curve>
  <Saving State Information in CGI Scripts Destination="1;1216;0;1.00076;0;0.557823;0;0;1;0" Open="false">
   <URL Query Parameters Destination="1;1218;0;1.00076;0;0.164777;0;0;1;0" Open="false"/>
   <Hidden Form Input Fields Destination="1;1218;0;1.00076;0;0.772487;0;0;1;0" Open="false"/>
   <HTTP “Cookies” Destination="1;1219;0;1.00076;0;0.500378;0;0;1;0" Open="false">
    <Creating a cookie Destination="1;1220;0;1.00076;0;0.237339;0;0;1;0" Open="false"/>
    <Receiving a cookie Destination="1;1221;0;1.00076;0;0.241875;0;0;1;0" Open="false"/>
    <Using cookies in CGI scripts Destination="1;1221;0;1.00076;0;0.610733;0;0;1;0" Open="false"/>
    <Handling cookies with the urllib.request module Destination="1;1222;0;1.00076;0;0.509448;0;0;1;0" Open="false"/>
   </HTTP “Cookies”>
   <Server-Side Databases Destination="1;1223;0;1.00076;0;0.594104;0;0;1;0" Open="false"/>
   <Extensions to the CGI Model Destination="1;1224;0;1.00076;0;0.300831;0;0;1;0" Open="false"/>
   <Combining Techniques Destination="1;1225;0;1.00076;0;0.137566;0;0;1;0" Open="false"/>
  </Saving State Information in CGI Scripts>
  <The Hello World Selector Destination="1;1225;0;1.00076;0;0.477702;0;0;1;0" Open="false">
   <Checking for Missing and Invalid Inputs Destination="1;1232;0;1.00076;0;0.482237;0;0;1;0" Open="false"/>
  </The Hello World Selector>
  <Refactoring Code for Maintainability Destination="1;1234;0;1.00076;0;0.560847;0;0;1;0" Open="false">
   <Step 1: Sharing Objects Between Pages—A New Input Form Destination="1;1235;0;1.00076;0;0.557823;0;0;1;0" Open="false"/>
   <Step 2: A Reusable Form Mock-Up Utility Destination="1;1238;0;1.00076;0;0.745276;0;0;1;0" Open="false"/>
   <Step 3: Putting It All Together—A New Reply Script Destination="1;1241;0;1.00076;0;0.482237;0;0;1;0" Open="false"/>
  </Refactoring Code for Maintainability>
  <More on HTML and URL Escapes Destination="1;1243;0;1.00076;0;0.793651;0;0;1;0" Open="false">
   <URL Escape Code Conventions Destination="1;1244;0;1.00076;0;0.553288;0;0;1;0" Open="false"/>
   <Python HTML and URL Escape Tools Destination="1;1245;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
   <Escaping HTML Code Destination="1;1245;0;1.00076;0;0.772487;0;0;1;0" Open="false"/>
   <Escaping URLs Destination="1;1246;0;1.00076;0;0.603175;0;0;1;0" Open="false"/>
   <Escaping URLs Embedded in HTML Code Destination="1;1247;0;1.00076;0;0.739229;0;0;1;0" Open="false">
    <HTML and URL conflicts: & Destination="1;1248;0;1.00076;0;0.3613;0;0;1;0" Open="false"/>
    <Avoiding conflicts Destination="1;1249;0;1.00076;0;0.20257;0;0;1;0" Open="false"/>
   </Escaping URLs Embedded in HTML Code>
  </More on HTML and URL Escapes>
  <Transferring Files to Clients and Servers Destination="1;1251;0;1.00076;0;0.551776;0;0;1;0" Open="false">
   <Displaying Arbitrary Server Files on the Client Destination="1;1253;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Handling private files and errors Destination="1;1257;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
   </Displaying Arbitrary Server Files on the Client>
   <Uploading Client Files to the Server Destination="1;1260;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Handling client path formats Destination="1;1266;0;1.00076;0;0.453515;0;0;1;0" Open="false"/>
   </Uploading Client Files to the Server>
   <More Than One Way to Push Bits over the Net Destination="1;1269;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  </Transferring Files to Clients and Servers>
 </Chapter 15. Server-Side Scripting>
 <Chapter 16. The PyMailCGI Server Destination="1;1271;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Things to Do When Visiting Chicago” Destination="1;1271;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <The PyMailCGI Website Destination="1;1272;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <Implementation Overview Destination="1;1272;0;1.00076;0;0.385488;0;0;1;0" Open="false"/>
   <New in This Fourth Edition (Version 3.0) Destination="1;1275;0;1.00076;0;0.219199;0;0;1;0" Open="false"/>
   <New in the Prior Edition (Version 2.0) Destination="1;1277;0;1.00076;0;0.1678;0;0;1;0" Open="false"/>
   <Presentation Overview Destination="1;1278;0;1.00076;0;0.429327;0;0;1;0" Open="false"/>
   <Running This Chapter’s Examples Destination="1;1279;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
  </The PyMailCGI Website>
  <The Root Page Destination="1;1281;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <Configuring PyMailCGI Destination="1;1282;0;1.00076;0;0.758881;0;0;1;0" Open="false"/>
  </The Root Page>
  <Sending Mail by SMTP Destination="1;1283;0;1.00076;0;0.75737;0;0;1;0" Open="false">
   <The Message Composition Page Destination="1;1284;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
   <The Send Mail Script Destination="1;1284;0;1.00076;0;0.719577;0;0;1;0" Open="false"/>
   <Error Pages Destination="1;1288;0;1.00076;0;0.453515;0;0;1;0" Open="false"/>
   <Common Look-and-Feel Destination="1;1288;0;1.00076;0;0.681784;0;0;1;0" Open="false"/>
   <Using the Send Mail Script Outside a Browser Destination="1;1289;0;1.00076;0;0.631897;0;0;1;0" Open="false"/>
  </Sending Mail by SMTP>
  <Reading POP Email Destination="1;1291;0;1.00076;0;0.793651;0;0;1;0" Open="false">
   <The POP Password Page Destination="1;1292;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <The Mail Selection List Page Destination="1;1293;0;1.00076;0;0.61678;0;0;1;0" Open="false"/>
   <Passing State Information in URL Link Parameters Destination="1;1296;0;1.00076;0;0.622827;0;0;1;0" Open="false"/>
   <Security Protocols Destination="1;1299;0;1.00076;0;0.553288;0;0;1;0" Open="false">
    <Reading mail with direct URLs Destination="1;1300;0;1.00076;0;0.530612;0;0;1;0" Open="false"/>
   </Security Protocols>
   <The Message View Page Destination="1;1301;0;1.00076;0;0.397581;0;0;1;0" Open="false"/>
   <Passing State Information in HTML Hidden Input Fields Destination="1;1304;0;1.00076;0;0.498866;0;0;1;0" Open="false"/>
   <Escaping Mail Text and Passwords in HTML Destination="1;1306;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  </Reading POP Email>
  <Processing Fetched Mail Destination="1;1308;0;1.00076;0;0.229781;0;0;1;0" Open="false">
   <Reply and Forward Destination="1;1309;0;1.00076;0;0.778534;0;0;1;0" Open="false"/>
   <Delete Destination="1;1310;0;1.00076;0;0.769463;0;0;1;0" Open="false"/>
   <Deletions and POP Message Numbers Destination="1;1314;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Inbox synchronization error potential Destination="1;1314;0;1.00076;0;0.406652;0;0;1;0" Open="false"/>
    <Alternative: Passing header text in hidden input fields (PyMailCGI_2.1) Destination="1;1315;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
    <Alternative: Server-side files for headers Destination="1;1317;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
    <Alternative: Delete on load Destination="1;1317;0;1.00076;0;0.675737;0;0;1;0" Open="false"/>
   </Deletions and POP Message Numbers>
  </Processing Fetched Mail>
  <Utility Modules Destination="1;1318;0;1.00076;0;0.196523;0;0;1;0" Open="false">
   <External Components and Configuration Destination="1;1318;0;1.00076;0;0.386999;0;0;1;0" Open="false"/>
   <POP Mail Interface Destination="1;1319;0;1.00076;0;0.311413;0;0;1;0" Open="false"/>
   <POP Password Encryption Destination="1;1320;0;1.00076;0;0.329554;0;0;1;0" Open="false">
    <Manual data encryption: rotor (defunct) Destination="1;1321;0;1.00076;0;0.353741;0;0;1;0" Open="false"/>
    <Manual data encryption: PyCrypto Destination="1;1322;0;1.00076;0;0.507937;0;0;1;0" Open="false"/>
    <HTTPS: Secure HTTP transmissions Destination="1;1323;0;1.00076;0;0.337113;0;0;1;0" Open="false"/>
    <Secure cookies Destination="1;1324;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <The secret.py module Destination="1;1324;0;1.00076;0;0.217687;0;0;1;0" Open="false"/>
    <Rolling your own encryptor Destination="1;1328;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </POP Password Encryption>
   <Common Utilities Module Destination="1;1328;0;1.00076;0;0.624339;0;0;1;0" Open="false"/>
  </Utility Modules>
  <Web Scripting Trade-Offs Destination="1;1333;0;1.00076;0;0.647014;0;0;1;0" Open="false">
   <PyMailCGI Versus PyMailGUI Destination="1;1334;0;1.00076;0;0.137566;0;0;1;0" Open="false"/>
   <The Web Versus the Desktop Destination="1;1335;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Other Approaches Destination="1;1338;0;1.00076;0;0.191988;0;0;1;0" Open="false"/>
  </Web Scripting Trade-Offs>
 </Chapter 16. The PyMailCGI Server>
</Part IV. Internet Programming>
<Part V. Tools and Techniques Destination="1;1343;0;1.00076;0;0.0786092;0;0;1;0" Open="false">
 <Chapter 17. Databases and Persistence Destination="1;1345;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Give Me an Order of Persistence, but Hold the Pickles” Destination="1;1345;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <Persistence Options in Python Destination="1;1345;0;1.00076;0;0.606198;0;0;1;0" Open="false"/>
  <DBM Files Destination="1;1347;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <Using DBM Files Destination="1;1347;0;1.00076;0;0.311413;0;0;1;0" Open="false"/>
   <DBM Details: Files, Portability, and Close Destination="1;1350;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  </DBM Files>
  <Pickled Objects Destination="1;1351;0;1.00076;0;0.39607;0;0;1;0" Open="false">
   <Using Object Pickling Destination="1;1352;0;1.00076;0;0.219199;0;0;1;0" Open="false"/>
   <Pickling in Action Destination="1;1353;0;1.00076;0;0.500378;0;0;1;0" Open="false"/>
   <Pickle Details: Protocols, Binary Modes, and _pickle Destination="1;1356;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  </Pickled Objects>
  <Shelve Files Destination="1;1357;0;1.00076;0;0.25548;0;0;1;0" Open="false">
   <Using Shelves Destination="1;1358;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Storing Built-in Object Types in Shelves Destination="1;1359;0;1.00076;0;0.780045;0;0;1;0" Open="false"/>
   <Storing Class Instances in Shelves Destination="1;1360;0;1.00076;0;0.786092;0;0;1;0" Open="false"/>
   <Changing Classes of Objects Stored in Shelves Destination="1;1362;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
   <Shelve Constraints Destination="1;1363;0;1.00076;0;0.61678;0;0;1;0" Open="false">
    <Keys must be strings (and str) Destination="1;1363;0;1.00076;0;0.707483;0;0;1;0" Open="false"/>
    <Objects are unique only within a key Destination="1;1364;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
    <Updates must treat shelves as fetch-modify-store mappings Destination="1;1364;0;1.00076;0;0.386999;0;0;1;0" Open="false"/>
    <Concurrent updates are not directly supported Destination="1;1364;0;1.00076;0;0.689342;0;0;1;0" Open="false"/>
    <Underlying DBM format portability Destination="1;1365;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </Shelve Constraints>
   <Pickled Class Constraints Destination="1;1365;0;1.00076;0;0.492819;0;0;1;0" Open="false"/>
   <Other Shelve Limitations Destination="1;1366;0;1.00076;0;0.51096;0;0;1;0" Open="false"/>
  </Shelve Files>
  <The ZODB Object-Oriented Database Destination="1;1367;0;1.00076;0;0.119426;0;0;1;0" Open="false">
   <The Mostly Missing ZODB Tutorial Destination="1;1368;0;1.00076;0;0.571429;0;0;1;0" Open="false"/>
  </The ZODB Object-Oriented Database>
  <SQL Database Interfaces Destination="1;1371;0;1.00076;0;0.219199;0;0;1;0" Open="false">
   <SQL Interface Overview Destination="1;1372;0;1.00076;0;0.474679;0;0;1;0" Open="false"/>
   <An SQL Database API Tutorial with SQLite Destination="1;1374;0;1.00076;0;0.668178;0;0;1;0" Open="false">
    <Getting started Destination="1;1375;0;1.00076;0;0.393046;0;0;1;0" Open="false"/>
    <Making databases and tables Destination="1;1376;0;1.00076;0;0.191988;0;0;1;0" Open="false"/>
    <Adding records Destination="1;1376;0;1.00076;0;0.497354;0;0;1;0" Open="false"/>
    <Running queries Destination="1;1378;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Running updates Destination="1;1380;0;1.00076;0;0.39607;0;0;1;0" Open="false"/>
   </An SQL Database API Tutorial with SQLite>
   <Building Record Dictionaries Destination="1;1381;0;1.00076;0;0.303855;0;0;1;0" Open="false">
    <Using table descriptions Destination="1;1381;0;1.00076;0;0.486772;0;0;1;0" Open="false"/>
    <Record dictionaries construction Destination="1;1382;0;1.00076;0;0.450491;0;0;1;0" Open="false"/>
    <Automating with scripts and modules Destination="1;1383;0;1.00076;0;0.527589;0;0;1;0" Open="false"/>
   </Building Record Dictionaries>
   <Tying the Pieces Together Destination="1;1384;0;1.00076;0;0.715042;0;0;1;0" Open="false"/>
   <Loading Database Tables from Files Destination="1;1386;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Loading with SQL and Python Destination="1;1386;0;1.00076;0;0.169312;0;0;1;0" Open="false"/>
    <Python versus SQL Destination="1;1387;0;1.00076;0;0.622827;0;0;1;0" Open="false"/>
   </Loading Database Tables from Files>
   <SQL Utility Scripts Destination="1;1389;0;1.00076;0;0.500378;0;0;1;0" Open="false">
    <Table load scripts Destination="1;1389;0;1.00076;0;0.78458;0;0;1;0" Open="false"/>
    <Table display script Destination="1;1391;0;1.00076;0;0.273621;0;0;1;0" Open="false"/>
    <Using the scripts Destination="1;1393;0;1.00076;0;0.628874;0;0;1;0" Open="false"/>
   </SQL Utility Scripts>
   <SQL Resources Destination="1;1396;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
  </SQL Database Interfaces>
  <ORMs: Object Relational Mappers Destination="1;1396;0;1.00076;0;0.539683;0;0;1;0" Open="false"/>
  <PyForm: A Persistent Object Viewer (External) Destination="1;1398;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
 </Chapter 17. Databases and Persistence>
 <Chapter 18. Data Structures Destination="1;1401;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“Roses Are Red, Violets Are Blue; Lists Are Mutable, and So Is Set Foo” Destination="1;1401;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <Implementing Stacks Destination="1;1402;0;1.00076;0;0.219199;0;0;1;0" Open="false">
   <Built-in Options Destination="1;1402;0;1.00076;0;0.60771;0;0;1;0" Open="false"/>
   <A Stack Module Destination="1;1404;0;1.00076;0;0.293273;0;0;1;0" Open="false"/>
   <A Stack Class Destination="1;1406;0;1.00076;0;0.125472;0;0;1;0" Open="false"/>
   <Customization: Performance Monitors Destination="1;1408;0;1.00076;0;0.583522;0;0;1;0" Open="false"/>
   <Optimization: Tuple Tree Stacks Destination="1;1409;0;1.00076;0;0.76644;0;0;1;0" Open="false"/>
   <Optimization: In-Place List Modifications Destination="1;1411;0;1.00076;0;0.647014;0;0;1;0" Open="false"/>
   <Timing the Improvements Destination="1;1413;0;1.00076;0;0.125472;0;0;1;0" Open="false">
    <Results under Python 3.1 Destination="1;1414;0;1.00076;0;0.314437;0;0;1;0" Open="false"/>
    <More on performance analysis Destination="1;1415;0;1.00076;0;0.273621;0;0;1;0" Open="false"/>
   </Timing the Improvements>
  </Implementing Stacks>
  <Implementing Sets Destination="1;1415;0;1.00076;0;0.612245;0;0;1;0" Open="false">
   <Built-in Options Destination="1;1416;0;1.00076;0;0.25548;0;0;1;0" Open="false"/>
   <Set Functions Destination="1;1417;0;1.00076;0;0.538171;0;0;1;0" Open="false">
    <Supporting multiple operands Destination="1;1418;0;1.00076;0;0.452003;0;0;1;0" Open="false"/>
   </Set Functions>
   <Set Classes Destination="1;1419;0;1.00076;0;0.489796;0;0;1;0" Open="false"/>
   <Optimization: Moving Sets to Dictionaries Destination="1;1420;0;1.00076;0;0.699924;0;0;1;0" Open="false">
    <Timing the results under Python 3.1 Destination="1;1423;0;1.00076;0;0.139078;0;0;1;0" Open="false"/>
   </Optimization: Moving Sets to Dictionaries>
   <Adding Relational Algebra to Sets (External) Destination="1;1424;0;1.00076;0;0.329554;0;0;1;0" Open="false"/>
  </Implementing Sets>
  <Subclassing Built-in Types Destination="1;1425;0;1.00076;0;0.279667;0;0;1;0" Open="false"/>
  <Binary Search Trees Destination="1;1427;0;1.00076;0;0.119426;0;0;1;0" Open="false">
   <Built-in Options Destination="1;1427;0;1.00076;0;0.291761;0;0;1;0" Open="false"/>
   <Implementing Binary Trees Destination="1;1428;0;1.00076;0;0.383976;0;0;1;0" Open="false"/>
   <Trees with Both Keys and Values Destination="1;1430;0;1.00076;0;0.612245;0;0;1;0" Open="false"/>
  </Binary Search Trees>
  <Graph Searching Destination="1;1432;0;1.00076;0;0.119426;0;0;1;0" Open="false">
   <Implementing Graph Search Destination="1;1432;0;1.00076;0;0.773998;0;0;1;0" Open="false"/>
   <Moving Graphs to Classes Destination="1;1435;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
  </Graph Searching>
  <Permuting Sequences Destination="1;1437;0;1.00076;0;0.191988;0;0;1;0" Open="false"/>
  <Reversing and Sorting Sequences Destination="1;1439;0;1.00076;0;0.647014;0;0;1;0" Open="false">
   <Implementing Reversals Destination="1;1440;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Implementing Sorts Destination="1;1441;0;1.00076;0;0.430839;0;0;1;0" Open="false">
    <Adding comparison functions Destination="1;1442;0;1.00076;0;0.199546;0;0;1;0" Open="false"/>
   </Implementing Sorts>
   <Data Structures Versus Built-ins: The Conclusion Destination="1;1442;0;1.00076;0;0.792139;0;0;1;0" Open="false"/>
  </Reversing and Sorting Sequences>
  <PyTree: A Generic Tree Object Viewer Destination="1;1444;0;1.00076;0;0.500378;0;0;1;0" Open="false"/>
 </Chapter 18. Data Structures>
 <Chapter 19. Text and Language Destination="1;1447;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“See Jack Hack. Hack, Jack, Hack” Destination="1;1447;0;1.00076;0;0.320484;0;0;1;0" Open="false"/>
  <Strategies for Processing Text in Python Destination="1;1447;0;1.00076;0;0.662132;0;0;1;0" Open="false"/>
  <String Method Utilities Destination="1;1448;0;1.00076;0;0.577475;0;0;1;0" Open="false">
   <Templating with Replacements and Formats Destination="1;1450;0;1.00076;0;0.21164;0;0;1;0" Open="false"/>
   <Parsing with Splits and Joins Destination="1;1451;0;1.00076;0;0.247921;0;0;1;0" Open="false"/>
   <Summing Columns in a File Destination="1;1452;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Summing with zips and comprehensions Destination="1;1453;0;1.00076;0;0.139078;0;0;1;0" Open="false"/>
    <Summing with dictionaries Destination="1;1453;0;1.00076;0;0.699924;0;0;1;0" Open="false"/>
   </Summing Columns in a File>
   <Parsing and Unparsing Rule Strings Destination="1;1454;0;1.00076;0;0.633409;0;0;1;0" Open="false">
    <More on the holmes expert system shell Destination="1;1456;0;1.00076;0;0.429327;0;0;1;0" Open="false"/>
   </Parsing and Unparsing Rule Strings>
  </String Method Utilities>
  <Regular Expression Pattern Matching Destination="1;1457;0;1.00076;0;0.734694;0;0;1;0" Open="false">
   <The re Module Destination="1;1458;0;1.00076;0;0.273621;0;0;1;0" Open="false"/>
   <First Examples Destination="1;1458;0;1.00076;0;0.751323;0;0;1;0" Open="false"/>
   <String Operations Versus Patterns Destination="1;1460;0;1.00076;0;0.536659;0;0;1;0" Open="false"/>
   <Using the re Module Destination="1;1463;0;1.00076;0;0.320484;0;0;1;0" Open="false">
    <Module functions Destination="1;1463;0;1.00076;0;0.46712;0;0;1;0" Open="false"/>
    <Compiled pattern objects Destination="1;1464;0;1.00076;0;0.335601;0;0;1;0" Open="false"/>
    <Match objects Destination="1;1464;0;1.00076;0;0.636432;0;0;1;0" Open="false"/>
    <Regular expression patterns Destination="1;1465;0;1.00076;0;0.340136;0;0;1;0" Open="false"/>
   </Using the re Module>
   <More Pattern Examples Destination="1;1467;0;1.00076;0;0.485261;0;0;1;0" Open="false"/>
   <Scanning C Header Files for Patterns Destination="1;1469;0;1.00076;0;0.677249;0;0;1;0" Open="false"/>
  </Regular Expression Pattern Matching>
  <XML and HTML Parsing Destination="1;1471;0;1.00076;0;0.309902;0;0;1;0" Open="false">
   <XML Parsing in Action Destination="1;1472;0;1.00076;0;0.21164;0;0;1;0" Open="false">
    <Regular expression parsing Destination="1;1473;0;1.00076;0;0.137566;0;0;1;0" Open="false"/>
    <SAX parsing Destination="1;1473;0;1.00076;0;0.730159;0;0;1;0" Open="false"/>
    <DOM parsing Destination="1;1475;0;1.00076;0;0.182918;0;0;1;0" Open="false"/>
    <ElementTree parsing Destination="1;1476;0;1.00076;0;0.154195;0;0;1;0" Open="false"/>
    <Other XML topics Destination="1;1477;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </XML Parsing in Action>
   <HTML Parsing in Action Destination="1;1477;0;1.00076;0;0.619803;0;0;1;0" Open="false">
    <Handling HTML entity references (revisited) Destination="1;1479;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
    <Extracting plain text from HTML (revisited) Destination="1;1480;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   </HTML Parsing in Action>
  </XML and HTML Parsing>
  <Advanced Language Tools Destination="1;1480;0;1.00076;0;0.362812;0;0;1;0" Open="false"/>
  <Custom Language Parsers Destination="1;1482;0;1.00076;0;0.424792;0;0;1;0" Open="false">
   <The Expression Grammar Destination="1;1482;0;1.00076;0;0.715042;0;0;1;0" Open="false"/>
   <The Parser’s Code Destination="1;1483;0;1.00076;0;0.62585;0;0;1;0" Open="false"/>
   <Adding a Parse Tree Interpreter Destination="1;1491;0;1.00076;0;0.154195;0;0;1;0" Open="false"/>
   <Parse Tree Structure Destination="1;1496;0;1.00076;0;0.683296;0;0;1;0" Open="false"/>
   <Exploring Parse Trees with the PyTree GUI Destination="1;1498;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Parsers Versus Python Destination="1;1499;0;1.00076;0;0.25548;0;0;1;0" Open="false"/>
  </Custom Language Parsers>
  <PyCalc: A Calculator Program/Object Destination="1;1499;0;1.00076;0;0.721088;0;0;1;0" Open="false">
   <A Simple Calculator GUI Destination="1;1500;0;1.00076;0;0.137566;0;0;1;0" Open="false">
    <Building the GUI Destination="1;1501;0;1.00076;0;0.498866;0;0;1;0" Open="false"/>
    <Running code strings Destination="1;1502;0;1.00076;0;0.790627;0;0;1;0" Open="false"/>
    <Extending and attaching Destination="1;1503;0;1.00076;0;0.610733;0;0;1;0" Open="false"/>
   </A Simple Calculator GUI>
   <PyCalc—A “Real” Calculator GUI Destination="1;1505;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Running PyCalc Destination="1;1505;0;1.00076;0;0.716553;0;0;1;0" Open="false"/>
    <Evaluating expressions with stacks Destination="1;1507;0;1.00076;0;0.696901;0;0;1;0" Open="false"/>
    <PyCalc source code Destination="1;1511;0;1.00076;0;0.362812;0;0;1;0" Open="false"/>
    <Using PyCalc as a component Destination="1;1517;0;1.00076;0;0.386999;0;0;1;0" Open="false"/>
    <Adding new buttons in new components Destination="1;1519;0;1.00076;0;0.155707;0;0;1;0" Open="false"/>
   </PyCalc—A “Real” Calculator GUI>
  </PyCalc: A Calculator Program/Object>
 </Chapter 19. Text and Language>
 <Chapter 20. Python/C Integration Destination="1;1525;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“I Am Lost at C” Destination="1;1525;0;1.00076;0;0.320484;0;0;1;0" Open="false">
   <Extending and Embedding Destination="1;1526;0;1.00076;0;0.355253;0;0;1;0" Open="false"/>
  </“I Am Lost at C”>
  <Extending Python in C: Overview Destination="1;1528;0;1.00076;0;0.474679;0;0;1;0" Open="false"/>
  <A Simple C Extension Module Destination="1;1529;0;1.00076;0;0.311413;0;0;1;0" Open="false"/>
  <The SWIG Integration Code Generator Destination="1;1533;0;1.00076;0;0.311413;0;0;1;0" Open="false">
   <A Simple SWIG Example Destination="1;1533;0;1.00076;0;0.721088;0;0;1;0" Open="false"/>
  </The SWIG Integration Code Generator>
  <Wrapping C Environment Calls Destination="1;1537;0;1.00076;0;0.657596;0;0;1;0" Open="false">
   <Adding Wrapper Classes to Flat Libraries Destination="1;1541;0;1.00076;0;0.347695;0;0;1;0" Open="false"/>
   <Wrapping C Environment Calls with SWIG Destination="1;1542;0;1.00076;0;0.594104;0;0;1;0" Open="false"/>
  </Wrapping C Environment Calls>
  <Wrapping C++ Classes with SWIG Destination="1;1544;0;1.00076;0;0.305367;0;0;1;0" Open="false">
   <A Simple C++ Extension Class Destination="1;1545;0;1.00076;0;0.21164;0;0;1;0" Open="false"/>
   <Wrapping the C++ Class with SWIG Destination="1;1547;0;1.00076;0;0.500378;0;0;1;0" Open="false"/>
   <Using the C++ Class in Python Destination="1;1549;0;1.00076;0;0.545729;0;0;1;0" Open="false">
    <Using the low-level extension module Destination="1;1550;0;1.00076;0;0.595616;0;0;1;0" Open="false"/>
    <Subclassing the C++ class in Python Destination="1;1551;0;1.00076;0;0.444444;0;0;1;0" Open="false"/>
    <Exploring the wrappers interactively Destination="1;1552;0;1.00076;0;0.60771;0;0;1;0" Open="false"/>
   </Using the C++ Class in Python>
  </Wrapping C++ Classes with SWIG>
  <Other Extending Tools Destination="1;1553;0;1.00076;0;0.773998;0;0;1;0" Open="false"/>
  <Embedding Python in C: Overview Destination="1;1556;0;1.00076;0;0.656085;0;0;1;0" Open="false">
   <The C Embedding API Destination="1;1557;0;1.00076;0;0.21164;0;0;1;0" Open="false"/>
   <What Is Embedded Code? Destination="1;1558;0;1.00076;0;0.489796;0;0;1;0" Open="false"/>
  </Embedding Python in C: Overview>
  <Basic Embedding Techniques Destination="1;1560;0;1.00076;0;0.201058;0;0;1;0" Open="false">
   <Running Simple Code Strings Destination="1;1561;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
    <Compiling and running Destination="1;1561;0;1.00076;0;0.783069;0;0;1;0" Open="false"/>
   </Running Simple Code Strings>
   <Running Code Strings with Results and Namespaces Destination="1;1564;0;1.00076;0;0.480726;0;0;1;0" Open="false"/>
   <Calling Python Objects Destination="1;1566;0;1.00076;0;0.574452;0;0;1;0" Open="false"/>
   <Running Strings in Dictionaries Destination="1;1568;0;1.00076;0;0.25548;0;0;1;0" Open="false"/>
   <Precompiling Strings to Bytecode Destination="1;1570;0;1.00076;0;0.241875;0;0;1;0" Open="false"/>
  </Basic Embedding Techniques>
  <Registering Callback Handler Objects Destination="1;1572;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
   <Registration Implementation Destination="1;1573;0;1.00076;0;0.173847;0;0;1;0" Open="false"/>
  </Registering Callback Handler Objects>
  <Using Python Classes in C Destination="1;1577;0;1.00076;0;0.181406;0;0;1;0" Open="false"/>
  <Other Integration Topics Destination="1;1580;0;1.00076;0;0.380952;0;0;1;0" Open="false"/>
 </Chapter 20. Python/C Integration>
</Part V. Tools and Techniques>
<Part VI. The End Destination="1;1583;0;1.00076;0;0.0786092;0;0;1;0" Open="false">
 <Chapter 21. Conclusion: Python and the Development Cycle Destination="1;1585;0;1.00076;0;0.0816327;0;0;1;0" Open="false">
  <“That’s the End of the Book, Now Here’s the Meaning of Life” Destination="1;1586;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  <“Something’s Wrong with the Way We Program Computers” Destination="1;1586;0;1.00076;0;0.430839;0;0;1;0" Open="false"/>
  <The “Gilligan Factor” Destination="1;1586;0;1.00076;0;0.7226;0;0;1;0" Open="false"/>
  <Doing the Right Thing Destination="1;1587;0;1.00076;0;0.548753;0;0;1;0" Open="false">
   <The Static Language Build Cycle Destination="1;1588;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
   <Artificial Complexities Destination="1;1588;0;1.00076;0;0.365835;0;0;1;0" Open="false"/>
   <One Language Does Not Fit All Destination="1;1588;0;1.00076;0;0.530612;0;0;1;0" Open="false"/>
  </Doing the Right Thing>
  <Enter Python Destination="1;1589;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  <But What About That Bottleneck? Destination="1;1590;0;1.00076;0;0.488284;0;0;1;0" Open="false">
   <Python Provides Immediate Turnaround Destination="1;1591;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
   <Python Is “Executable Pseudocode” Destination="1;1592;0;1.00076;0;0.278156;0;0;1;0" Open="false"/>
   <Python Is OOP Done Right Destination="1;1592;0;1.00076;0;0.662132;0;0;1;0" Open="false"/>
   <Python Fosters Hybrid Applications Destination="1;1593;0;1.00076;0;0.119426;0;0;1;0" Open="false"/>
  </But What About That Bottleneck?>
  <On Sinking the Titanic Destination="1;1594;0;1.00076;0;0.737717;0;0;1;0" Open="false"/>
  <So What’s “Python: The Sequel”? Destination="1;1597;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>
  <In the Final Analysis… Destination="1;1597;0;1.00076;0;0.447468;0;0;1;0" Open="false"/>
 </Chapter 21. Conclusion: Python and the Development Cycle>
</Part VI. The End>
<Index Destination="1;1599;0;1.00076;0;0.0816327;0;0;1;0" Open="false"/>

failed to look up 1;7;0;1.00076;0;0.0816327;0;0;1;0
failed to look up 1;25;0;1.00076;0;0.0816327;0;0;1;0
failed to look up 1;25;0;1.00076;0;0.291761;0;0;1;0
failed to look up 1;26;0;1.00076;0;0.0816327;0;0;1;0
failed to look up 1;26;0;1.00076;0;0.21164;0;0;1;0
failed to look up 1;27;0;1.00076;0;0.0816327;0;0;1;0
failed to look up 1;27;0;1.00076;0;0.588057;0;0;1;0
failed to look up 1;28;0;1.00076;0;0.0816327;0;0;1;0
failed to look up 1;32;0;1.00076;0;0.544218;0;0;1;0
failed to look up 1;33;0;1.00076;0;0.485261;0;0;1;0
failed to look up 1;34;0;1.00076;0;0.0816327;0;0;1;0
failed to look up 1;35;0;1.00076;0;0.0816327;0;0;1;0
failed to look up 1;35;0;1.00076;0;0.643991;0;0;1;0
failed to look up 1;36;0;1.00076;0;0.604686;0;0;1;0
failed to look up 1;36;0;1.00076;0;0.702948;0;0;1;0
failed to look up 1;37;0;1.00076;0;0.489796;0;0;1;0
failed to look up 1;38;0;1.00076;0;0.0816327;0;0;1;0
failed to look up 1;38;0;1.00076;0;0.243386;0;0;1;0
failed to look up 1;38;0;1.00076;0;0.527589;0;0;1;0
failed to look up 1;39;0;1.00076;0;0.145125;0;0;1;0
failed to look up 1;39;0;1.00076;0;0.594104;0;0;1;0
failed to look up 1;43;0;1.00076;0;0.0786092;0;0;1;0
...

Thanks a lot!

C9t0 commented 9 years ago

Ohhh i have found it! It was a bug in my code based on a ambiguous part in the poppler lib.

My correctly working version looks like this:

    def __readToC(doc, inChapter: Chapter, node):
        n = node.firstChildElement()
        while(not n.isNull()):
            #build up this chapter
            subChapter = Chapter()
            subChapter.title = n.tagName()

            linkPage = 0
            dest = n.attribute("Destination")
            destName = n.attribute("DestinationName")
            if (dest):
                linkPage = popplerqt4.Poppler.LinkDestination(dest).pageNumber()
            elif (destName):
                linkPage = doc.linkDestination(destName).pageNumber()

            subChapter.startPage = linkPage - 1

            Book.__readToC(doc, subChapter, n)

            inChapter.chapters.append(subChapter)

            n = n.nextSiblingElement()
wbsoft commented 9 years ago

Great!! But thanks for taking the effort to report what could have been a buglet. Note that in your code linkDest could be 0, if the if and elif both fail :-)

C9t0 commented 9 years ago

Thanks for you comment, it was a really quick fix example ;-) Now this is also fixed :-D

And sorry that I have create a issue for a fault in my code.