diff --git a/index.html b/index.html
index 7806c53..bdf438a 100644
--- a/index.html
+++ b/index.html
@@ -25,6 +25,7 @@ h1:before,h2:before{content:''}
Also available on dead trees! Pre-order now, get it October 16th!
+
What’s New in “Dive Into Python 3”
Installing Python
@@ -48,6 +49,7 @@ h1:before,h2:before{content:''}
Special Method Names
Where to Go From Here
+
The book is freely licensed under the Creative Commons Attribution Share-Alike license. You can download it as HTML or PDF . Über-geeks can also clone the Mercurial repository:
diff --git a/table-of-contents.html b/table-of-contents.html
index 187b7a7..1443aea 100755
--- a/table-of-contents.html
+++ b/table-of-contents.html
@@ -1,425 +1,446 @@
-
-
-
Table of contents - Dive Into Python 3
-
-
-
-
-
-
-You are here: Home ‣ Dive Into Python 3 ‣
-
Table of Contents
-
-What’s New In “Dive Into Python 3”
-Installing Python
-
- Diving In
- Which Python Is Right For You?
- Installing on Microsoft Windows
- Installing on Mac OS X
- Installing on Ubuntu Linux
- Installing on Other Platforms
- Using The Python Shell
- Python Editors and IDEs
-
-Your first Python program
-
- Diving In
- Declaring functions
- Writing readable code
-
- Docstrings
-
- The import search path
- Everything is an object
-
- What’s an object?
-
- Indenting code
- Exceptions
- Running scripts
- Further reading
-
-Native Python datatypes
-
-Diving In
-Booleans
-Numbers
-
- Coercing integers to floats and vice-versa
- Common numerical operations
- Fractions
- Trigonometry
- Numbers in a boolean context
-
-Lists
-
- Creating a list
- Slicing a list
- Adding items to a list
- Searching for values in a list
- Lists in a boolean context
-
-Tuples
-
- Assigning Multiple Values At Once
-
-Sets
-
- Creating A Set
- Modifying A Set
- Removing Items From A Set
- Common Set Operations
- Sets In A Boolean Context
-
-Dictionaries
-
- Creating a dictionary
- Modifying a dictionary
- Mixed-value dictionaries
- Dictionaries in a boolean context
-
-None
-
- None in a boolean context
-
-Further reading
-
-Comprehensions
-
- Diving In
- Working With Files And Directories
-
- The Current Working Directory
- Working With Filenames and Directory Names
- Listing Directories
- Getting File Metadata
- Constructing Absolute Pathnames
-
- List Comprehensions
- Dictionary Comprehensions
-
- Other Fun Stuff To Do With Dictionary Comprehensions
-
- Set Comprehensions
- Further Reading
-
-Strings
-
- Some Boring Stuff You Need To Understand Before You Can Dive In
- Unicode
- Diving In
- Formatting Strings
-
- Compound Field Names
- Format Specifiers
-
- Other Common String Methods
-
- Slicing A String
-
- Strings vs. Bytes
- Postscript: Character Encoding Of Python Source Code
- Further Reading
-
-Regular expressions
-
- Diving In
- Case study: street addresses
- Case study: Roman numerals
-
- Checking for thousands
- Checking for hundreds
-
- Using the {n,m} Syntax
-
- Checking for tens and ones
-
- Verbose regular expressions
- Case study: parsing phone numbers
- Summary
-
-Closures & Generators
-
- Diving In
- I know, let’s use regular expressions!
- A list of functions
- A list of patterns
- A file of patterns
- Generators
-
- A Fibonacci generator
- A plural rule generator
-
-
-Classes & Iterators
-
- Diving In
- Defining Classes
- Instantiating Classes
- Instance Variables
- A Fibonacci iterator
- A Plural Rule Iterator
- Further Reading
-
-Advanced Iterators
-
- Diving In
- Finding all occurrences of a pattern
- Finding the unique items in a sequence
- Making assertions
- Generator expressions
- Calculating Permutations… The Lazy Way!
- Other Fun Stuff in the itertools Module
- A New Kind Of String Manipulation
- Evaluating Arbitrary Strings As Python Expressions
- Putting It All Together
- Further Reading
-
-Unit Testing
-
- (Not) Diving In
- A single Question
- “Halt and Catch Fire”
- More Halting, More Fire
- And One More Thing…
- A Pleasing Symmetry
- More Bad Input
-
-Refactoring
-
- Diving In
- Handling Changing Requirements
- Refactoring
- Summary
-
-Files
-
- Diving In
- Reading From Text Files
-
- Character Encoding Rears Its Ugly Head
- Stream Objects
- Reading Data From A Text File
- Closing Files
- Closing Files Automatically
- Reading Data One Line At A Time
-
- Writing to Text Files
-
- Character Encoding Again
-
- Binary Files
- Stream Objects From Non-File Sources
-
- Handling Compressed Files
-
- Standard Input, Output, and Error
-
- Redirecting Standard Output
-
- Further Reading
-
-XML
-
- Diving In
- A 5-Minute Crash Course in XML
- The Structure Of An Atom Feed
- Parsing XML
-
- Elements Are Lists
- Attributes Are Dictonaries
-
- Searching For Nodes Within An XML Document
- Going Further With lxml
-
- Customizing Your XML Parser
- Incremental Parsing
-
- Generating XML
- Further Reading
-
- Serializing Python Objects
-
- Diving In
-
- A Quick Note About The Examples in This Chapter
-
- Saving Data to a Pickle File
- Loading Data from a Pickle File
- Pickling Without a File
- Bytes and Strings Rear Their Ugly Heads Again
- Debugging Pickle Files
- Serializing Python Objects to be Read by Other Languages
- Saving Data to a JSON File
- Mapping of Python Datatypes to JSON
- Serializing Datatypes Unsupported by JSON
- Loading Data from a JSON File
- Further Reading
-
-HTTP Web Services
-
- Diving In
- Features of HTTP
-
- Caching
- Last-Modified Checking
- ETags
- Compression
- Redirects
-
- How Not To Fetch Data Over HTTP
- What’s On The Wire?
- Introducing httplib2
-
- How httplib2 Handles Caching
- How httplib2 Handles Last-Modified and ETag Headers
- How http2lib Handles Compression
- How httplib2 Handles Redirects
-
- Beyond HTTP GET
- Beyond HTTP POST
- Further Reading
-
-Case study: porting chardet to Python 3
-
- Diving In
- What is Character Encoding Auto-Detection?
-
- Isn’t That Impossible?
- Does Such An Algorithm Exist?
-
- Introducing The chardet Module
-
- UTF-n With A BOM
- Escaped Encodings
- Multi-Byte Encodings
- Single-Byte Encodings
- windows-1252
-
- Running 2to3
- A Short Digression Into Multi-File Modules
- Fixing What 2to3 Can’t
-
- False is invalid syntax
- No module named constants
- Name 'file' is not defined
- Can’t use a string pattern on a bytes-like object
- Can't convert 'bytes' object to str implicitly
- Unsupported operand type(s) for +: 'int' and 'bytes'
- ord() expected string of length 1, but int found
- Unorderable types: int() >= str()
- Global name 'reduce' is not defined
-
- Summary
-
-Packaging Python libraries
-
- Diving In
- Things Distutils Can’t Do For You
- Directory Structure
- Writing Your Setup Script
- Classifying Your Package
-
- Examples of Good Package Classifiers
-
- Specifying Additional Files With A Manifest
- Checking Your Setup Script for Errors
- Creating a Source Distribution
- Creating a Graphical Installer
-
- Building Installable Packages for Other Operating Systems
-
- Adding Your Software to The Python Package Index
- The Many Possible Futures of Python Packaging
- Further Reading
-
-Appendix A. Porting code to Python 3 with 2to3
-
- Diving In
- print statement
- Unicode string literals
- unicode() global function
- long data type
- <> comparison
- has_key() dictionary method
- Dictionary methods that return lists
- Modules that have been renamed or reorganized
-
- http
- urllib
- dbm
- xmlrpc
- Other modules
-
- Relative imports within a package
- next() iterator method
- filter() global function
- map() global function
- reduce() global function
- apply() global function
- intern() global function
- exec statement
- execfile statement
- repr literals (backticks)
- try...except statement
- raise statement
- throw method on generators
- xrange() global function
- raw_input() and input() global functions
- func_* function attributes
- xreadlines() I/O method
- lambda functions that take a tuple instead of multiple parameters
- Special method attributes
- __nonzero__ special method
- Octal literals
- sys.maxint
- callable() global function
- zip() global function
- StandardError() exception
- types module constants
- isinstance() global function
- basestring datatype
- itertools module
- sys.exc_type, sys.exc_value, sys.exc_traceback
- List comprehensions over tuples
- os.getcwdu() function
- Metaclasses
- Matters of style
-
- set() literals
- buffer() global function
- Whitespace around commas
- Common idioms
-
-
-Appendix B. Special Method Names
-
- Diving In
- Basics
- Classes That Act Like Iterators
- Computed Attributes
- Classes That Act Like Functions
- Classes That Act Like Sequences
- Classes That Act Like Dictionaries
- Classes That Act Like Numbers
- Classes That Can Be Compared
- Classes That Can Be Serialized
- Classes That Can Be Used in a with Block
- Really Esoteric Stuff
- Further Reading
-
-Appendix C. Where to go from here
-
- Things to read
- Where to look for Python 3-compatible code
-
-
-© 2001–9 Mark Pilgrim
-
+
+
+
Table of contents - Dive Into Python 3
+
+
+
+
+
+
+You are here: Home ‣ Dive Into Python 3 ‣
+
Table of Contents
+
+
+What’s New in “Dive Into Python 3”
+
+a.k.a. “the minus level”
+
+Installing Python
+
+Diving In
+Which Python Is Right For You?
+Installing on Microsoft Windows
+Installing on Mac OS X
+Installing on Ubuntu Linux
+Installing on Other Platforms
+Using The Python Shell
+Python Editors and IDEs
+
+Your First Python Program
+
+Diving In
+Declaring Functions
+
+Optional and Named Arguments
+
+Writing Readable Code
+
+Documentation Strings
+
+The import Search Path
+Everything Is An Object
+
+What’s An Object?
+
+Indenting Code
+Exceptions
+
+Catching Import Errors
+
+Unbound Variables
+Everything is Case-Sensitive
+Running Scripts
+Further Reading
+
+Native Datatypes
+
+Diving In
+Booleans
+Numbers
+
+Coercing Integers To Floats And Vice-Versa
+Common Numerical Operations
+Fractions
+Trigonometry
+Numbers In A Boolean Context
+
+Lists
+
+Creating A List
+Slicing A List
+Adding Items To A List
+Searching For Values In A List
+Removing Items From A List
+Removing Items From A List: Bonus Round
+Lists In A Boolean Context
+
+Tuples
+
+Tuples In A Boolean Context
+Assigning Multiple Values At Once
+
+Sets
+
+Creating A Set
+Modifying A Set
+Removing Items From A Set
+Common Set Operations
+Sets In A Boolean Context
+
+Dictionaries
+
+Creating A Dictionary
+Modifying A Dictionary
+Mixed-Value Dictionaries
+Dictionaries In A Boolean Context
+
+None
+
+None In A Boolean Context
+
+Further Reading
+
+Comprehensions
+
+Diving In
+Working With Files And Directories
+
+The Current Working Directory
+Working With Filenames and Directory Names
+Listing Directories
+Getting File Metadata
+Constructing Absolute Pathnames
+
+List Comprehensions
+Dictionary Comprehensions
+
+Other Fun Stuff To Do With Dictionary Comprehensions
+
+Set Comprehensions
+Further Reading
+
+Strings
+
+Some Boring Stuff You Need To Understand Before You Can Dive In
+Unicode
+Diving In
+Formatting Strings
+
+Compound Field Names
+Format Specifiers
+
+Other Common String Methods
+
+Slicing A String
+
+Strings vs. Bytes
+Postscript: Character Encoding Of Python Source Code
+Further Reading
+
+Regular Expressions
+
+Diving In
+Case Study: Street Addresses
+Case Study: Roman Numerals
+
+Checking For Thousands
+Checking For Hundreds
+
+Using The {n,m} Syntax
+
+Checking For Tens And Ones
+
+Verbose Regular Expressions
+Case study: Parsing Phone Numbers
+Summary
+
+Closures & Generators
+
+Diving In
+I Know, Let’s Use Regular Expressions!
+A List Of Functions
+A List Of Patterns
+A File Of Patterns
+Generators
+
+A Fibonacci Generator
+A Plural Rule Generator
+
+Further Reading
+
+Classes & Iterators
+
+Diving In
+Defining Classes
+
+The __init__() Method
+
+Instantiating Classes
+Instance Variables
+A Fibonacci Iterator
+A Plural Rule Iterator
+Further Reading
+
+Advanced Iterators
+
+Diving In
+Finding all occurrences of a pattern
+Finding the unique items in a sequence
+Making assertions
+Generator expressions
+Calculating Permutations… The Lazy Way!
+Other Fun Stuff in the itertools Module
+A New Kind Of String Manipulation
+Evaluating Arbitrary Strings As Python Expressions
+Putting It All Together
+Further Reading
+
+Unit Testing
+
+(Not) Diving In
+A Single Question
+“Halt And Catch Fire”
+More Halting, More Fire
+And One More Thing…
+A Pleasing Symmetry
+More Bad Input
+
+Refactoring
+
+Diving In
+Handling Changing Requirements
+Refactoring
+Summary
+
+Files
+
+Diving In
+Reading From Text Files
+
+Character Encoding Rears Its Ugly Head
+Stream Objects
+Reading Data From A Text File
+Closing Files
+Closing Files Automatically
+Reading Data One Line At A Time
+
+Writing to Text Files
+
+Character Encoding Again
+
+Binary Files
+Streams Objects From Non-File Sources
+
+Handling Compressed Files
+
+Standard Input, Output, and Error
+
+Redirecting Standard Output
+
+Further Reading
+
+XML
+
+Diving In
+A 5-Minute Crash Course in XML
+The Structure Of An Atom Feed
+Parsing XML
+
+Elements Are Lists
+Attributes Are Dictonaries
+
+Searching For Nodes Within An XML Document
+Going Further With lxml
+Generating XML
+Parsing Broken XML
+Further Reading
+
+Serializing Python Objects
+
+Diving In
+
+A Quick Note About The Examples in This Chapter
+
+Saving Data to a Pickle File
+Loading Data from a Pickle File
+Pickling Without a File
+Bytes and Strings Rear Their Ugly Heads Again
+Debugging Pickle Files
+Serializing Python Objects to be Read by Other Languages
+Saving Data to a JSON File
+Mapping of Python Datatypes to JSON
+Serializing Datatypes Unsupported by JSON
+Loading Data from a JSON File
+Further Reading
+
+HTTP Web Services
+
+Diving In
+Features of HTTP
+
+Caching
+Last-Modified Checking
+ETags
+Compression
+Redirects
+
+How Not To Fetch Data Over HTTP
+What’s On The Wire?
+Introducing httplib2
+
+A Short Digression To Explain Why httplib2 Returns Bytes Instead of Strings
+How httplib2 Handles Caching
+How httplib2 Handles Last-Modified and ETag Headers
+How http2lib Handles Compression
+How httplib2 Handles Redirects
+
+Beyond HTTP GET
+Beyond HTTP POST
+Further Reading
+
+Case Study: Porting chardet to Python 3
+
+Diving In
+What is Character Encoding Auto-Detection?
+
+Isn’t That Impossible?
+Does Such An Algorithm Exist?
+
+Introducing The chardet Module
+
+UTF-n With A BOM
+Escaped Encodings
+Multi-Byte Encodings
+Single-Byte Encodings
+windows-1252
+
+Running 2to3
+A Short Digression Into Multi-File Modules
+Fixing What 2to3 Can’t
+
+False is invalid syntax
+No module named constants
+Name 'file' is not defined
+Can’t use a string pattern on a bytes-like object
+Can't convert 'bytes' object to str implicitly
+Unsupported operand type(s) for +: 'int' and 'bytes'
+ord() expected string of length 1, but int found
+Unorderable types: int() >= str()
+Global name 'reduce' is not defined
+
+Summary
+
+Packaging Python Libraries
+
+Diving In
+Things Distutils Can’t Do For You
+Directory Structure
+Writing Your Setup Script
+Classifying Your Package
+
+Examples of Good Package Classifiers
+
+Specifying Additional Files With A Manifest
+Checking Your Setup Script for Errors
+Creating a Source Distribution
+Creating a Graphical Installer
+
+Building Installable Packages for Other Operating Systems
+
+Adding Your Software to The Python Package Index
+The Many Possible Futures of Python Packaging
+Further Reading
+
+Porting Code to Python 3 with 2to3
+
+Diving In
+print statement
+Unicode string literals
+unicode() global function
+long data type
+<> comparison
+has_key() dictionary method
+Dictionary methods that return lists
+Modules that have been renamed or reorganized
+
+http
+urllib
+dbm
+xmlrpc
+Other modules
+
+Relative imports within a package
+next() iterator method
+filter() global function
+map() global function
+reduce() global function
+apply() global function
+intern() global function
+exec statement
+execfile statement
+repr literals (backticks)
+try...except statement
+raise statement
+throw method on generators
+xrange() global function
+raw_input() and input() global functions
+func_* function attributes
+xreadlines() I/O method
+lambda functions that take a tuple instead of multiple parameters
+Special method attributes
+__nonzero__ special method
+Octal literals
+sys.maxint
+callable() global function
+zip() global function
+StandardError exception
+types module constants
+isinstance() global function
+basestring datatype
+itertools module
+sys.exc_type, sys.exc_value, sys.exc_traceback
+List comprehensions over tuples
+os.getcwdu() function
+Metaclasses
+Matters of style
+
+set() literals (explicit)
+buffer() global function (explicit)
+Whitespace around commas (explicit)
+Common idioms (explicit)
+
+
+Special Method Names
+
+Diving In
+Basics
+Classes That Act Like Iterators
+Computed Attributes
+Classes That Act Like Functions
+Classes That Act Like Sequences
+Classes That Act Like Dictionaries
+Classes That Act Like Numbers
+Classes That Can Be Compared
+Classes That Can Be Serialized
+Classes That Can Be Used in a with Block
+Really Esoteric Stuff
+Further Reading
+
+Where to Go From Here
+
+Things to Read
+Where To Look For Python 3-Compatible Code
+
+
+
+© 2001–9 Mark Pilgrim
+
diff --git a/util/buildtoc.py b/util/buildtoc.py
new file mode 100644
index 0000000..f98e2c9
--- /dev/null
+++ b/util/buildtoc.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python3
+
+import re
+
+# get list of chapters
+chapters = []
+for line in open('index.html'):
+ if not line.count('
', 1)[0])
+sections = {}
+
+for filename in chapters:
+ chapter_id = filename.split(".", 1)[0]
+ with open(filename, encoding="utf-8") as f: data = f.read()
+ sections[chapter_id] = re.findall("(.*?) ')[1].split('')[0]
+
+full_toc = ['', '']
+chapter_id = ''
+for line in short_toc.splitlines():
+ if not line.count('', '>', line)
+ line = line.replace(' ', ' '.format(chapter_id))
+ full_toc.append(line)
+ section_number = 0
+ previous_section_level = section_level = 1
+ for section_level, section_id, section_title in sections[chapter_id]:
+ section_level = int(section_level)
+ if section_level < previous_section_level:
+ full_toc.append(' ')
+ elif section_level > previous_section_level:
+ full_toc.append('')
+ section_number += 1
+ full_toc.append('{2} '.format(chapter_id, section_id, section_title))
+ previous_section_level = section_level
+ section_level = int(section_level)
+ while (section_level > 1):
+ full_toc.append(' ')
+ section_level -= 1
+full_toc.append('')
+full_toc.append('')
+with open('table-of-contents.html', encoding="utf-8") as f: data = f.read()
+with open('table-of-contents.html', mode="w", encoding="utf-8") as f:
+ f.write(data.split('')[0] + "\n".join(full_toc) + data.split('')[1])
diff --git a/util/htmlminimizer.py b/util/htmlminimizer.py
index 6539757..42a74af 100755
--- a/util/htmlminimizer.py
+++ b/util/htmlminimizer.py
@@ -21,6 +21,10 @@ with open(output_file, 'w', encoding="utf-8") as _out, open(input_file, encoding
if "url(i/" in line:
line = line.replace("url(i/", "url(http://" + next(available_server) + "/dip3/")
+ # remove selected comments (but not all comments, because some are conditional comments for IE compat)
+ line = line.replace('', '')
+ line = line.replace('', '')
+
# replace entities with Unicode characters
for e in re.findall('&(.+?);', line):
if e in ('lt', 'amp', 'quot', 'apos', 'nbsp'):