As usual, both I and O'Reilly's production staff have worked very hard to make this book as typo-free and accurate as possible. And as usual, a set of errata have managed to find there way into the book anyhow. Although this is perhaps the most typo-free book I have written to date, errata are an unavoidable fact of life in this field.
To put a more personal spin on that, after writing 9 computer books over the last 12 years, I believe I can state with some authority that book publishing is no place for a perfectionist to be! As you'll notice in the lists below, even if an author doesn't break things, the editing and production processes almost certainly will.
Below is the current list of corrections, notes, and updates for this edition of the book. Only the first of these sections is true errata; the other two sections contain supplemental information. If you find something else that looks like a possible error, please contact either O'Reilly or me; we'd like to patch these in future printings or editions. Also see O'Reilly's errata page for this book, which may or may not intersect with my list here over time.
Sections on this page:
This section lists genuine corrections for the book -- miswordings, code bugs, and so on. Items here:
In the Python 3.0 changes section, this bullet item describes the demise of the `X` backquotes expression, but seems to show this using straight quotes as 'X'. This was changed this way somewhere in the production pipeline, but is a fairly minor issue, given the surrounding text. Backquotes are formatted properly later, on pages 96 and 136.
Also in the Python 3.0 section, a comma in program code was deleted, also somewhere in the production process. The "except name value" should read as "except name, value" as described later in the book (see pages 583, 594, 612, and 614).
The "Python mplements" should be "Python implements", of course. Alas, this was spelled correctly in the final draft I sent to O'Reilly, but was broken somewhere in the production pipeline. It originally had 2 spaces before the word, which accounts for the edit. (I make mistakes too, but I've come to believe that the number of typos in a book is directly proportional to the number of hands that touch it before it is published.)
On page 161, near the end of Table 8-2, an entry lists D4 = dict.fromvalues(['a', 'b']) as an alternative construction technique. There is no fromvalues dictionary method. This should be dict.fromkeys(['a', 'b']), as shown later on page 170, and as can be surmised by running a dir(dict) call interactively.
In the very first sentence on this page, the "rwords" should be "words". This was also correct in the final draft of the book I submitted, but was broken by the production process as well (all the more frustrating, given that that process is supposed to fix spelling errors, not introduce them after the material leaves the author's hands).
Sentence 2 of paragraph 4 on this page incorrectly states that the * operator, and hence the times function "will work on numbers (performing multiplication), two strings or a string and a number (performing repetition), or any other combination of objects supporting the expected interface". This is incorrect -- * works on two numbers, or a string and a number, but not on two strings. That is, string * string is not a valid operation. In fact, if you pass two strings into the times function, it generates an exception, the point of the next paragraph in the book.
This was also something I DID NOT SAY in the final draft I submitted to the publisher. My version mentions the numbers and string/number cases shown in the code listings, but not the obviously incorrect string/string case -- this third case was added by production. Specifically, the editing/production process broke the meaning here by adding the part "two strings or". This was despite the fact that the editors knew little about Python, and did not ask about the accuracy of the insertion. Unfortunately, a minor insertion of text like this can have a major impact on meaning in a technical book, and some editors are not always as careful as they should be.
In the first code listing on this page, the 4th line is indented incorrectly. The "return action" line should be moved 4 spaces to the right, to be indented the same as the line "def action(X):". That is, the "action" function is returned by the "maker" function. As is, the code's indentation generates a syntax error. This will probably be easy for most readers to spot, especially given the description, and the other similar examples in this area of the book. It appears to have been the product of an unfortunate cut-and-paste from the IDLE GUI during the writing phase.
In 2 spots of this section, I transposed the I1/I2 and C2/C3 variable names. The typo should be apparent from the surrounding text, but it could also be a bit confusing given the introductory nature of this section. Specifically: in this section's very first sentence, "C2.w" should be "C3.w"; in the last sentence of this section's second paragraph, "C3.w(I1)" should be "C3.w(I2).". The more realistic "bob.giveRaise" example at the end of this section clarifies the intent here. Also see pages 467 and 484 for more complete descriptions of method call mapping.
In the answer to quiz question #2 on this page, the text states that the inheritance search for an attribute looks "first in the instance object, then in the class the instance was created from, then in all higher superclasses, progressing from the top to the bottom of the object tree, and from left to right (by default)". The "top to the bottom" part of this is incorrect; the search actually proceeds from bottom to top in the tree, as implied by the earlier parts of this sentence.
This was also something I DID NOT SAY in the final draft I submitted to the publisher. In my version, the last part of this sentence correctly says the search is "depth-first and left-to-right (by default)", instead of top-to-bottom, which is clearly wrong. In fact, the correct bottom-to-top order through the search tree is stated explicitly numerous times in this chapter. This was broken by an editor who expanded the wording here, which is especially unfortunate in an answer to a chapter quiz question!
There is a case typo in the commented-out line here. It should read "#print C.m.X", with the uppercase "C". This is in a comment, so it's not a bug, and the code would fail if run even with the case fix. It might be confusing to some human readers, though, given that Python is case-sensitive.
This section lists notes and comments about the text, designed to augment or clarify the published material. Items here:
This page describes the upcoming set literal and set comprehension syntax to be added in Python 3.0: the new literal syntax {1, 3, 2} is equivalent to the current set([1, 3, 2]), and the new set comprehension syntax {f(x) for x in S if P(x)} is like the current generator expression set(f(x) for x in S if P(x)).
In addition, although not mentioned in the text, Python 3.0 will now also have a dictionary comprehension syntax: {key:val for (key, val) in zip(keys, vals)}, works like the current dict(zip(keys, vals)), and {x:x for x in items} is like the current dict((x, x) for x in items). Here's a summary of all the comprehension alternatives in 3.0 (the last 2 are new):
>>> [x*x for x in range(10)] # list comprehension: builds list ([x, y] is a list)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> (x*x for x in range(10)) # generator exppression: produces items (parens often optional)
<generator object at 0x009E7328>
>>> {x*x for x in range(10)} # set comprehension, new in 3.0 ({x, y} is a set)
{0, 1, 4, 81, 64, 9, 16, 49, 25, 36}
>>> {x:x*x for x in range(10)} # dictionary comprehension, new in 3.0 ({x:x, y:y} is a dict)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
The 5th bullet up from the end of this page should probably mention that "print" might not be reserved in 3.0, due to the new print function replacing the current statement. See the next item for more on this; 3.0 changes are still uncertain. Note that "yield" will likely still be reserved, since it is changing from a statement to an expression, not a built-in function.
On pages xxxviii and 234, I mention that the print statement is to become a function call in 3.0, to support more features. To help describe how it will work, the following is a function that emulates much of the working of the 3.0 print function. Also note that "print" might no longer be a reserved word in 3.0; it is today, though, which is why we can't call this function "print":
"emulate most of the 3.0 print function"
import sys
def print30(*args, **kargs):
sep = kargs.get('sep', ' ') # keyword arg defaults
end = kargs.get('end', '\n')
file = kargs.get('file', sys.stdout)
output = ''
for arg in args:
output += (str(arg) + sep)
file.write(output + end)
if __name__ == '__main__':
print30(1, 2, 3) # "1 2 3\n"
print30(1, 2, 3, sep='') # "123\n"
print30(4, 5, 6, sep='', end='') # "456"
print30() # "\n"
print30(1, 2, 3, sep='??', file=sys.stderr) # "1??2??3??\n"
On this page, the iteration alternatives timing script uses time.time to compute elapsed time. This works fine for this example, but on Windows, using time.clock instead may give better timer precision than time.time (time.clock is microsecond granularity). On Linux, however, time.time is the preferred alternative. See the library manuals for more details, or use the suggested timeit module to finesse such details altogether.
On page 139, there is a loop that uses the ord(char) function to convert a binary digit string to integer. It works as shown and serves to demo ord, but note that the same effect can be had in Python 2.5 today by calling the built-in function int(binstr, 2), giving an explicit base of 2. See page 105 for other examples of using a base with this built-in function.
That is the only built-in support for binary representation in Python 2.5, though. Perhaps a more interesting exercise is to also convert the other way, from integer to binary digit string. As mentioned at the top of page xxxviii, Python 3.0 will support this with a new built-in function bin(int), and will also have a new 0b1010 binary literal syntax for integers. However, to-binary conversion can be emulated in code today, by using the bitwise operations described on page 103 to extract bits. The following module, binary.py, shows one way to code this (albeit with possible platform size and endianness dependencies that could be tailored by checking sys.byteorder and sys.maxint):
def fromBinary(B):
"""
convert binary string B to its decimal integer value;
this can also be done today by the built-in: int(B, 2);
caveat: this doesn't do any error checking in the string
"""
I = 0
while B:
I = I * 2 + (ord(B[0]) - ord('0')) # or: I << 2
B = B[1:]
return I
def toBinary(I):
"""
convert 32-bit integer I to a binary digits string;
there is no built-in for this today, but 3.0 will have
a new bin(I) call; 3.0 also supports binary literals:
0b1010 will equal 10, and bin(10) will return "0b1010";
caveat: this depends on integer size and bit endian-ness
"""
B = ''
while I:
low = I & 0x00000001 # extract low bit
I = (I >> 1) & 0x7FFFFFFF # shift off low bit, 0 high
B = chr(ord('0') + low) + B # or: '1' if low else '0'
return B
if __name__ == '__main__':
# self-test code
for binstr in ('1101', '01111111', '10000000', '10000001', '0', '111'):
print fromBinary(binstr)
for intobj in (13, 127, 128, 129, 1, -1, -13):
print toBinary(intobj)
This section lists noteworthy updates to Python or other packages mentioned, since the book's publication.
Back to this book's main page