Errata


Print Print Icon

Submit your own errata for this product.


The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.


Color Key: Serious Technical Mistake Minor Technical Mistake Language or formatting error Typo Question



Version Location Description Submitted By
Printed Page 48
1st sentence on page.

"as it does in C:"
should read
"as it does in C."

Anonymous 
Printed Page 68
Question 6

In the section which says, "What happens if you try to index a nonexistent key
d(D['d'])?", the formatting seems to indicate that d is a function, which is
having the argument D['d'] applied to it.

In the next sentence, the part which says, "... nonexistent key d (e.g.,
D['d']=='spam')" makes use of the "e.g. to clearly differentiate between the
use of the key 'd' and it's example use.

The original sentence should use some text to separate the two items such as
"d (e.g., D['d'])" to make it clearer.

Anonymous 
Printed Page 68
Question 7, part C: 2nd sentence

"How about the;"
Should read
"How about"

Anonymous 
Printed Page 82
4th paragraph

And finally, Python also lets you move a compound statement's body up to the header
line. provided the body is just a simple

--- Not only simple statements, but simple statements separated by
semicolons also do it:

if 1: print 1; print 'one'; print 'ogyin'; print 'egy'; print 'eins'

Anonymous 
Printed Page 87
2nd paragraph of the *first* edition

Since a prime number is "any integer greater than one if its only positive divisors
(factors) are one and itself", the smallest prime number is 2 and your algorithm
should not report as prime any integer less than 2. However, the algorithm published
in chapter 3 indicates that certain integers less than 2 are also prime. If you were
to add a test so that only values of y > 1 are reported as prime, the blemish would
be fixed. The following echo indicates that the algorithm published in the first
edition is incorrect.:

>>> y = -2
>>> while x>1 and y > 1:
if y % x == 0:
print y, 'has factor', x
break
x = x - 1
else:
print y, 'is prime'

-2 is prime
>>> y = 1
>>> while x>1 and y > 1:
if y % x == 0:
print y, 'has factor', x
break
x = x - 1
else:
print y, 'is prime'

1 is prime

Anonymous 
Printed Page 221
Table 8-2, setattr()

"creates of changes attribute"
----------^

shouldn't this be :

"creates or changes attribute"
----------^

Anonymous 
Printed Page 238
1st code example

The unpacking code example has a tuple assignment:

start, stop = stop, start + struct.calcsize('B'*num_bytes)

This will only work if the tuple elements get assigned
sequentially (i.e., that start is updated on the RHS of
the equation before the update of stop). This is not
the case (thank God!). I believe the correct code is:

start, stop = stop, stop + struct.calcsize('B'*num_bytes)

Anonymous 
Printed Page 282
last paragraph, first sentence

COM stands for Component Object Model, not Common Object Model as it says in the
book.

Anonymous 
Printed Page 341-342
class Adder, __init__ definition at bottom of page and next page

The superclass Adder's __init__ method defaults the start parameter to the empty list. This is an invalid type for the subclass DictAdder.

To illustrate the problem:

>>> from ex6 import *
>>> d = DictAdder()
>>> d + {'a':1}
Traceback (innermost last):
File "<stdin>", line 1, in ?
File "ex6.py", line 7, in __add__
self.x = self.add(self.x, y)
File "ex6.py", line 19, in add
for k in x.keys():
AttributeError: keys

Anonymous 
Printed Page 351
fix_paragraphs_with_word function

The function fix_paragraphs_with_word in the solution to Exercise 3
from Chapter 8 is wrong. Luckily it works for this particular input
(pepper.txt), but in the general case it is flawed as shown
in the comments below:

... omitted the correct part of the file ...

def fix_paragraphs_with_word(paragraphs, word) :
lenword = len(word)
for par_no in range (len(paragraphs)) :
p = paragraphs[par_no]
wordpositions = find_indices_for(p, word)
if wordpositions == [] : return <<<<<<< WRONG!!!
You must not return here!
Still not done with other
paragraphs from the list.
Should be "continue" instead
of return.

for start in wordpositions:
# look for 'pepper' ahead
indexpepper = string.find(p, 'pepper') <<<<< WRONG!!!
This finds "pepper" before the
word red or green. Should search
from "start" only as in
string.find(p, 'pepper', start)

if indexpepper == -1: return -1 <<<<<< WRONG!!!
Again the same blunder. You are
still not done with all paragraphs.
Should be "break" to exit to
the outer for loop.

if string.strip(p[start:indexpepper]) != " : <<< WRONG!!!
There will always be something
other than whitespace, namely,
the word (red or green). Should be
p[start+lenword:indexpepper]

# something other than whitespace in between!
continue
where = indexpepper+len('pepper')
if p[where:where+len('corn')] == 'corn' :
# it's immediately followed by 'corn'!
continue
if string.find(p, 'salad') < where:
# it's not followed by 'salad'
continue
# Finally! we get to do a change!
p = p[:start] + 'bell' + p[start+lenword:]
paragraphs [par_no] = p # change mutable argument!

fix_paragraphs_with_word(paragraphs, 'red')
fix_paragraphs_with_word(paragraphs, 'green')

for paragraph in paragraphs:
print paragraph+'
' <<<< WRONG!!!
Here you print two extra blank
lines at the end of the file.
One due to '
' the other due
to the print statement itself.

I cannot explain so many mistakes in such a simple code except
considering that too many continue and (quite wrong) return
statements were applied in a small loop-in-a-loop construct.
Cleaning the logic a little and applying the short-cut property of
and operator in Python (just as in C, C++, Java, Perl, or Lisp)
the authors could have come with the following solution:

import string

file = open('pepper.txt')
paragraphs = string.split(file.read(), '

')

def find_positions(haystack, needle):
positions = []
offset = 0
while 1:
i = string.find(haystack, needle)
if i == -1:
return positions # no more matches
positions.append(i + offset)
haystack = haystack[i + len(needle):]
offset = offset + i + len(needle)

def replace_in_para_list(paragraphs, word):
L = len(word)
for n in range(len(paragraphs)):
p = paragraphs[n]
positions = find_positions(p, word)
if positions != []:
for pos in positions:
i = string.find(p, 'pepper', pos)
if i == -1:
break # try next paragraph
end = i + len('pepper')
if (len(string.strip(p[pos+L:i])) == 0 and
p[end:end+len('corn')] != 'corn' and
string.find(p, 'salad', end) != -1):
p = p[:pos] + 'bell' + p[pos + L:]
paragraphs[n] = p

replace_in_para_list(paragraphs, 'red')
replace_in_para_list(paragraphs, 'green')

print string.join(paragraphs, '

'),

Anonymous 
Printed Page 479
2nd code section from bottom

self.__init__(self, *args, **kw)

should be:

Base.__init__(self, *args, **kw)

Anonymous