The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Corrected".
The following errata were submitted by our customers and approved as valid errors by the author or editor.
| Version |
Location |
Description |
Submitted By |
Corrected |
| Printed |
Page xi
Last paragraph |
Missing word: "...how **TO** use "cookies" to deal with..."
AM: reader's right, s/how use/how to use/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
xi
Last paragraph |
Missing word: "...how **TO** use "cookies" to deal with..."
AM: reader's right, s/how use/how to use/
|
Anonymous |
Jul 2008 |
| Printed |
Page 4
4th paragraph |
If you find you are [MORE???] productive with Java or C# than with C or Fortran...
AM: reader's right, s/productive/more productive/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
4
4th paragraph |
If you find you are [MORE???] productive with Java or C# than with C or Fortran...
AM: reader's right, s/productive/more productive/
|
Anonymous |
Jul 2008 |
| Printed |
Page 49
3rd paragraph |
The sentence "For example, x=x+y does not modify the object to which name x was
originally bound" is incorrect, I think. Suppose x and y belong to a user-defined
class in which __add__ has been defined. Suppose __add__(self, other)
changes some
attribute (say 'value') of self. Suppose we make the statements:
z=x
x = x+y
print z.value
The point of the discussion in the book is that x is reassigned, not changed in
place. However, the object originally bound to x will be changed in
place, and that change can be seen here in z.
The introduction of a custom __add__ is not so out of left field here, since
the book is contrasting the situation to when the object has a custom __iadd__.
AM: substitute /For example, x=x+y/For example, the assignment in x=x+y/ .
|
Anonymous |
Jul 2008 |
| Other Digital Version |
49
3rd paragraph |
The sentence "For example, x=x+y does not modify the object to which name x was
originally bound" is incorrect, I think. Suppose x and y belong to a user-defined
class in which __add__ has been defined. Suppose __add__(self, other)
changes some
attribute (say 'value') of self. Suppose we make the statements:
z=x
x = x+y
print z.value
The point of the discussion in the book is that x is reassigned, not changed in
place. However, the object originally bound to x will be changed in
place, and that change can be seen here in z.
The introduction of a custom __add__ is not so out of left field here, since
the book is contrasting the situation to when the object has a custom __iadd__.
AM: substitute /For example, x=x+y/For example, the assignment in x=x+y/ .
|
Anonymous |
Jul 2008 |
| Printed |
Page 80
paragraph 4, 6 |
RecursionLimitExceeded is not a standard exception. A RuntimeError
with the message
"maximum recursion depth exceeded" is raised instead.
AM: reader's right; s/RecursionLimitExceeded exceptions/"maximum
recursion depth exceeded" exceptions/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
80
paragraph 4, 6 |
RecursionLimitExceeded is not a standard exception. A RuntimeError
with the message
"maximum recursion depth exceeded" is raised instead.
AM: reader's right; s/RecursionLimitExceeded exceptions/"maximum
recursion depth exceeded" exceptions/
|
Anonymous |
Jul 2008 |
| Printed |
Page 87
Attributes of instance objects paragraph |
Class C7 is an old-style class. The author always used new style ones
in the first part of the chapter.
AM: The slight style variation can be fixed by s/class C7: pass/class C7(object):
pass/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
87
Attributes of instance objects paragraph |
Class C7 is an old-style class. The author always used new style ones
in the first part of the chapter.
AM: The slight style variation can be fixed by s/class C7: pass/class C7(object):
pass/
|
Anonymous |
Jul 2008 |
| Printed |
Page 110
Example at bottom of page |
In the __getitem__ example, self.indices should be index.indices; also, one
parenthesis seems to be missing at the end.
AM: reader's right on both accounts, s/self.indices/index.indices/ AND
add a ) at the end of that same line
|
Anonymous |
Jul 2008 |
| Other Digital Version |
110
Example at bottom of page |
In the __getitem__ example, self.indices should be index.indices; also, one
parenthesis seems to be missing at the end.
AM: reader's right on both accounts, s/self.indices/index.indices/ AND
add a ) at the end of that same line
|
Anonymous |
Jul 2008 |
| Printed |
Page 165
In 'ord' section |
The integer code returned for unicode is [0,65534], but shouldn't it
be 65535? But if it cannot return 65535, I would have appreciated knowing why it wouldn't.
AM: reader's right, s/65534/65535/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
165
In 'ord' section |
The integer code returned for unicode is [0,65534], but shouldn't it
be 65535? But if it cannot return 65535, I would have appreciated knowing why it wouldn't.
AM: reader's right, s/65534/65535/
|
Anonymous |
Jul 2008 |
| Printed |
Page 166
End of 'reduce' section |
result of reduce() is the product of a sequence of numbers, but it is getting bound to 'thesum'.
AM: reader's right, to reduce confusion s/thesum/theprod/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
166
End of 'reduce' section |
result of reduce() is the product of a sequence of numbers, but it is getting bound to 'thesum'.
AM: reader's right, to reduce confusion s/thesum/theprod/
|
Anonymous |
Jul 2008 |
| Printed |
Page 175
2nd paragraph |
>>> import collections, operator
>>> def sorted_histograms(seq):
d = collections.defaultdict(int)
for item in seq: d[item] += 1
print d
return sorted(d.iteritems, key=operator.itemgetter(1), reverse=True)
>>> a = [ "b", "c", "d", "b", "c", "c", "e", "d"]
>>> b = sorted_histograms(a)
defaultdict(<type 'int'>, {'c': 3, 'b': 2, 'e': 1, 'd': 2})
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
b = sorted_histograms(a)
File "<pyshell#2>", line 9, in sorted_histograms
return sorted(d.iteritems, key=operator.itemgetter(1), reverse=True)
TypeError: 'builtin_function_or_method' object is not iterable
>>> b
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
b
NameError: name 'b' is not defined
AM: reader's right, s/sorted(d.iteritems, /sorted(d.iteritems(), /
|
Anonymous |
Jul 2008 |
| Other Digital Version |
175
2nd paragraph |
>>> import collections, operator
>>> def sorted_histograms(seq):
d = collections.defaultdict(int)
for item in seq: d[item] += 1
print d
return sorted(d.iteritems, key=operator.itemgetter(1), reverse=True)
>>> a = [ "b", "c", "d", "b", "c", "c", "e", "d"]
>>> b = sorted_histograms(a)
defaultdict(<type 'int'>, {'c': 3, 'b': 2, 'e': 1, 'd': 2})
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
b = sorted_histograms(a)
File "<pyshell#2>", line 9, in sorted_histograms
return sorted(d.iteritems, key=operator.itemgetter(1), reverse=True)
TypeError: 'builtin_function_or_method' object is not iterable
>>> b
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
b
NameError: name 'b' is not defined
AM: reader's right, s/sorted(d.iteritems, /sorted(d.iteritems(), /
|
Anonymous |
Jul 2008 |
| Printed |
Page 177
Description of heappop |
Doesn't heappop run in O(log(len(alist))) time instead of
O(len(alist))? If it was
O(len(alist)), then heapsort would be O(n^2).
AM: reader's right, s/O(len(alist))/O(log(len(alist)))/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
177
Description of heappop |
Doesn't heappop run in O(log(len(alist))) time instead of
O(len(alist))? If it was
O(len(alist)), then heapsort would be O(n^2).
AM: reader's right, s/O(len(alist))/O(log(len(alist)))/
|
Anonymous |
Jul 2008 |
| Printed |
Page 183
Third attribute description, "cycle" |
Syntax summary is "count(iterable)", should be "cycle(iterable)"
AM: reader's right, s/count/cycle/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
183
Third attribute description, "cycle" |
Syntax summary is "count(iterable)", should be "cycle(iterable)"
AM: reader's right, s/count/cycle/
|
Anonymous |
Jul 2008 |
| Printed |
Page 187
3rd section |
The string method 'decode' which was introduced in Python 2.2 is missing.
http://docs.python.org/lib/string-methods.html
AM: reader's right. Just before 'encode' where it alphabetically belongs, with s/encode/decode/ in
the syntax summary as well, and short description
Returns a (typically unicode) string obtained from s with the given coded and error
handling. See "Unicode" on page 198 for more details.
i.e. basically the same as encode except for the parenthetical note
that the result is typically Unicode. Maybe the apparent duplication
is what caused the snip...?
|
Anonymous |
Jul 2008 |
| Other Digital Version |
187
3rd section |
The string method 'decode' which was introduced in Python 2.2 is missing.
http://docs.python.org/lib/string-methods.html
AM: reader's right. Just before 'encode' where it alphabetically belongs, with s/encode/decode/ in
the syntax summary as well, and short description
Returns a (typically unicode) string obtained from s with the given coded and error
handling. See "Unicode" on page 198 for more details.
i.e. basically the same as encode except for the parenthetical note
that the result is typically Unicode. Maybe the apparent duplication
is what caused the snip...?
|
Anonymous |
Jul 2008 |
| Printed |
Page 189
Description of rstrip |
Text reads "Returns a copy of s, removing leading characters that are found in string x"
but should read "trailing" instead of "leading".
AM: reader's right, s/leading/trailing/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
189
Description of rstrip |
Text reads "Returns a copy of s, removing leading characters that are found in string x"
but should read "trailing" instead of "leading".
AM: reader's right, s/leading/trailing/
|
Anonymous |
Jul 2008 |
| Printed |
Page 197
3rd paragraph (if we count the examples as a paragraph) |
It explains "textwrap.fill". It says that...
"""
Returns a single multiline string that is exactly equal to
'
'.join(fill(s,width)).
"""
... and it should say ...
"""
Returns a single multiline string that is exactly equal to
'
'.join(wrap(s,width)).
"""
AM: Reader's right, s/fill/wrap/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
197
3rd paragraph (if we count the examples as a paragraph) |
It explains "textwrap.fill". It says that...
"""
Returns a single multiline string that is exactly equal to
'
'.join(fill(s,width)).
"""
... and it should say ...
"""
Returns a single multiline string that is exactly equal to
'
'.join(wrap(s,width)).
"""
AM: Reader's right, s/fill/wrap/
|
Anonymous |
Jul 2008 |
| Printed |
Page 198
The repr module |
Should refer to page 166, not 198.
Also index on page 691 should reference page 166 under repr (in addition to 198)
|
Anonymous |
Sep 2007 |
| Printed |
Page 203
4th paragraph |
It says "rE", it should say "RE".
|
Anonymous |
Sep 2007 |
| Printed |
Page 207
first code snippet |
The third line of code is wrapping down, it must not.
AM: reader's right, break the line typographically right after the
colon ':' and put 'print' etc on the NEXT typographical line indented four spaces
|
Anonymous |
Jul 2008 |
| Other Digital Version |
207
first code snippet |
The third line of code is wrapping down, it must not.
AM: reader's right, break the line typographically right after the
colon ':' and put 'print' etc on the NEXT typographical line indented four spaces
|
Anonymous |
Jul 2008 |
| Printed |
Page 231
first code snippet |
The third line of code is wrapping down, it must not.
AM: reader's right, put a at the end of the third line and indent the following
(fourth) line four spaces
|
Anonymous |
Jul 2008 |
| Other Digital Version |
231
first code snippet |
The third line of code is wrapping down, it must not.
AM: reader's right, put a at the end of the third line and indent the following
(fourth) line four spaces
|
Anonymous |
Jul 2008 |
| Printed |
Page 307
strftime |
fmt parameter is missing in function prototype.
AM: reader's right, s/d.strftime()/d.strftime(fmt)/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
307
strftime |
fmt parameter is missing in function prototype.
AM: reader's right, s/d.strftime()/d.strftime(fmt)/
|
Anonymous |
Jul 2008 |
| Printed |
Page 310
5th method description |
The method name, in the syntax description, says "d.timezone(tz)", it should say "d.astimezone(tz)".
AM: reader's right, s/timezone/astimezone/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
310
5th method description |
The method name, in the syntax description, says "d.timezone(tz)", it should say "d.astimezone(tz)".
AM: reader's right, s/timezone/astimezone/
|
Anonymous |
Jul 2008 |
| Printed |
Page 311
strftime |
fmt argument missing from prototype.
AM: reader's right, s/d.strftime()/d.strftime(fmt)/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
311
strftime |
fmt argument missing from prototype.
AM: reader's right, s/d.strftime()/d.strftime(fmt)/
|
Anonymous |
Jul 2008 |
| Printed |
Page 312
example usage for timedelta |
The second timedelta() call in the "print repr(timedelta...)" examples should be
changed from
timedelta(minutes=0.5)
to
timedelta(hours=-1)
for the example output to be correct.
AM: reader's right, s/minutes=0.5/hours=-1/ in that second example.
|
Anonymous |
Jul 2008 |
| Other Digital Version |
312
example usage for timedelta |
The second timedelta() call in the "print repr(timedelta...)" examples should be
changed from
timedelta(minutes=0.5)
to
timedelta(hours=-1)
for the example output to be correct.
AM: reader's right, s/minutes=0.5/hours=-1/ in that second example.
|
Anonymous |
Jul 2008 |
| Printed |
Page 350
Bottom, and next 2 pages (not fixed by errata) |
I don't know how critical exception handling is to the content of your code samples. A lot of books state up-front that they've done a minimal job in this regard, but I didn't see such a disclaimer in this book. I would have marked this as a "Serious technical mistake" except for this fact. It certainly could be serious for anyone who naively uses this in production code.
You present the ExternalInterfacing, Serializer, and Worker classes in the book (and to a lesser degree in the errata). But note what happens if the thread run() method encounters an exception by calling self.externalCallable. I believe the ExternalInterfacing/Serializer/Worker thread will terminate, and the thread calling request()/apply(), which is blocking by calling q.get(), will deadlock (assuming it keeps running at all, as http://docs.python.org/lib/module-thread.html suggests for the earlier thread module).
Note that the Worker thread may terminate but since it posts results asynchronously, this doesn't necessarily cause an actual deadlock. I don't see this addressed in the errata so I wanted to mention it.
My suggestion is to catch exceptions in run(), return them in lieu of results, detect exceptions in request()/apply(), and raise them when they occur. Raising isn't really possible for the Worker, but the exception could at least be put into the result queue.
Note from the Author or Editor: Add in the front matter of the book a disclaimer: "the example code in this book is intended to provide concise examples, and therefore often does not deal with possible errors and anomalies with the rock-solidity required in production code".
|
Anonymous |
|
| Printed |
Page 458
Bottom of Example 18-2 |
space between equal signs:
if __name__= ='__main__':
should be:
if __name__=='__main__':
|
Anonymous |
Sep 2007 |
| Printed |
Page 458
2nd paragraph under Example 18-2 |
method 'testExactly1Argument' referred to in paragraph is actually
testExactlyOneArgument in Example 18-2
AM: reader's right, s/testExactly1Argument/testExactlyOneArgument/ in that text
|
Anonymous |
Jul 2008 |
| Other Digital Version |
458
2nd paragraph under Example 18-2 |
method 'testExactly1Argument' referred to in paragraph is actually
testExactlyOneArgument in Example 18-2
AM: reader's right, s/testExactly1Argument/testExactlyOneArgument/ in that text
|
Anonymous |
Jul 2008 |
| Printed |
Page 485
Last code section |
The example in this section was how to quickly sort a list of strings based on the second word in
each string. The operator.itemgetter technique incorrectly sorts based on the second character in
each string, not the second word.
Maybe use something like:
L.sort(key=lambda x: x.split()[1])
AM: reader's right that the code at the almost-bottom of p.485 is incorrect, but the right fix
is to change those two lines into the following two lines instead:
def secondword(s): return s.split()[1]
L.sort(key=secondword)
|
Anonymous |
Jul 2008 |
| Other Digital Version |
485
Last code section |
The example in this section was how to quickly sort a list of strings based on the second word in
each string. The operator.itemgetter technique incorrectly sorts based on the second character in
each string, not the second word.
Maybe use something like:
L.sort(key=lambda x: x.split()[1])
AM: reader's right that the code at the almost-bottom of p.485 is incorrect, but the right fix
is to change those two lines into the following two lines instead:
def secondword(s): return s.split()[1]
L.sort(key=secondword)
|
Anonymous |
Jul 2008 |
| Printed |
Page 511
1st paragraph after "Network News" title |
It talks about POP protocol, and should talk about NNTP protocol.
AM: reader's right, s/POP/NNTP/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
511
1st paragraph after "Network News" title |
It talks about POP protocol, and should talk about NNTP protocol.
AM: reader's right, s/POP/NNTP/
|
Anonymous |
Jul 2008 |
| Printed |
Page 518
Bottom of page |
Example program produces error message:
"Traceback (most recent call last):
File "C:xmlrpctest.py", line 6, in <module>
results = proxy.meerkat.getItems({'search':'Python', 'num_items':7})
File "C:Python25Libxmlrpclib.py", line 1147, in __call__
return self.__send(self.__name, args)
File "C:Python25Libxmlrpclib.py", line 1437, in __request
verbose=self.__verbose
File "C:Python25Libxmlrpclib.py", line 1191, in request
headers
ProtocolError: <ProtocolError for
www.oreillynet.com/meerkat/xml-rpc/server.php: 301 Moved Permanently>"
AM: reader's right, Meerkat is no longer available and was shut down March 2, 2006. Delete example.
|
Anonymous |
Jul 2008 |
| Other Digital Version |
518
Bottom of page |
Example program produces error message:
"Traceback (most recent call last):
File "C:xmlrpctest.py", line 6, in <module>
results = proxy.meerkat.getItems({'search':'Python', 'num_items':7})
File "C:Python25Libxmlrpclib.py", line 1147, in __call__
return self.__send(self.__name, args)
File "C:Python25Libxmlrpclib.py", line 1437, in __request
verbose=self.__verbose
File "C:Python25Libxmlrpclib.py", line 1191, in request
headers
ProtocolError: <ProtocolError for
www.oreillynet.com/meerkat/xml-rpc/server.php: 301 Moved Permanently>"
AM: reader's right, Meerkat is no longer available and was shut down March 2, 2006. Delete example.
|
Anonymous |
Jul 2008 |
| Printed |
Page 524
Middle of page, End of 3rd paragraph |
getsockopt example reads:
import socket
s = socket.socket()
print s.getsockopt(s.SOL_SOCKET, s.S0_REUSEADDR)
Code should read:
import socket
s = socket.socket()
print s.getsockopt(socket.SOL_SOCKET, socket.S0_REUSEADDR)
AM: Reader's right, pls change as he's indicated (except it's SO_REUSEADDR as in the book, not
S0_REUSEADDR as he indicates -- an uppercase O, *not* a zero digit).
|
Anonymous |
Jul 2008 |
| Other Digital Version |
524
Middle of page, End of 3rd paragraph |
getsockopt example reads:
import socket
s = socket.socket()
print s.getsockopt(s.SOL_SOCKET, s.S0_REUSEADDR)
Code should read:
import socket
s = socket.socket()
print s.getsockopt(socket.SOL_SOCKET, socket.S0_REUSEADDR)
AM: Reader's right, pls change as he's indicated (except it's SO_REUSEADDR as in the book, not
S0_REUSEADDR as he indicates -- an uppercase O, *not* a zero digit).
|
Anonymous |
Jul 2008 |
| Printed |
Page 541
3rd reactor method description, connectTCP |
The syntax description says "r.listenTCP(", should be "r.connectTCP("
AM: Reader's right, s/listenTCP/connectTCP/
|
Anonymous |
Jul 2008 |
| Other Digital Version |
541
3rd reactor method description, connectTCP |
The syntax description says "r.listenTCP(", should be "r.connectTCP("
AM: Reader's right, s/listenTCP/connectTCP/
|
Anonymous |
Jul 2008 |
| Printed |
Page 664
2 |
Using jythonc (jython version 2.2.1):
If you want to see a jython class from java you need to extend a parent java class. So
class APythonClass:
...
must be
class APythonClass(java.lang.object):
...
Jython 2.5rc2 doesn't use jythonc (http://www.jython.org/Project/jythonc.html).
Note from the Author or Editor: The reader is correct: please change `class APythonClass:` to `class APythonClass(java.lang.object):`. The book does NOT cover versions 2.5 and later so the remark about 2.5rc2 may be omitted.
|
Maurizio Lupo |
|
| Printed |
Page 693
sys module main entry in index |
There is no page number next to the listing. There should be a reference
to page 168, which is where the main discussion of the sys module begins.
|
Anonymous |
Sep 2007 |