Errata

Python Cookbook

Errata for Python Cookbook

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 Note Update

Version Location Description Submitted by Date submitted
PDF Page 2.15
10th paragraph

>>> name = 'Guido'
>>> n = 37
>>> '%(name) has %(n) messages.' % vars()
'Guido has 37 messages.'
>>>
missing 's' after '%()', the correct pattern should be:
'%(name)s has %(n)s messages.' % vars()

JunyuRen  Mar 05, 2021 
Printed Page 18
Bottom

The slice positions are wrongly calculated.

Existing in Book:
record = '....................100 .......513.25 ..........'
cost = int(record[20:32]) * float(record[40:48])
SHARES = slice(20,32)
PRICE = slice(40,48)


Corrected One:
record = '....................100 .......513.25 ..........'
cost = int(record[20:23]) * float(record[31:38])
SHARES = slice(20,23)
PRICE = slice(31,38)

Nehemiah Jacob  Apr 17, 2014 
PDF Page 24
Second code sample in Discussion

Missing right brackets at the end of the lines

Bill  Dec 11, 2014 
Printed Page 28
in the middle of the page

in the book, it shows:

>>> list(compress(addresses, more5))
['5800 E 58TH', '4801 N BROADWAY','1039 W GRANVILLE']

the correct result should be:
>>> list(compress(addresses, more5))
['5800 E 58TH', '1060 W ADDISON', '4801 N BROADWAY']

Tony Tang  Jul 19, 2016 
PDF Page 28
2nd code fragment

You should probably put a comma after '2122 N CLARK', because the output is quite confusing as it is now.
If you do, make sure to adjust the following code fragment as well:

>>> list(compress(addresses, more5))
['5800 E 58TH', '4801 N BROADWAY', '1039 W GRANVILLE']

should be:
>>> list(compress(addresses, more5))
['5800 E 58TH', '1060 W ADDISON', '4801 N BROADWAY']

Anonymous  Jul 20, 2016 
PDF Page 28
2nd paragraph

in the PDF, the output of >>>list(compress(addresses, more5))
['5800 E 58TH', '4801 N BROADWAY', '1039 W GRANVILLE']
however, it shoud be >>>list(compress(addresses, more5))
['5800 E 58TH', '1060 W ADDISON', '4801 N BROADWAY']

DavidWang  Apr 16, 2022 
ePub Page 43
text below first code block

The first sentence would be clearer as:
In this example, the pattern r'\"(.*)\"' is attempting to match text enclosed inside double quotes.

Gregory Sherman  Apr 09, 2018 
ePub Page 53
2.15 first code in Discussion

using Python 3.6.5

>>> name = 'Guido'
>>> n = 37
>>> '%(name) has %(n) messages.' % vars()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: unsupported format character 'm' (0x6d) at index 17
>>>

Gregory Sherman  Oct 23, 2018 
PDF Page 69
top

PRINT = r'(P<PRINT>print)'
NAME = r'(P<NAME>[a-zA-Z_][a-zA-Z_0-9]*)'

the pattern is (?P<name>), missing “?”

Marco  Dec 14, 2020 
PDF Page 83
4th paragraph == 2nd paragraph in "Solution"

The paragraph states: "When a value is exactly halfway between two choices, the behavior of round is to round
to the nearest even digit. That is, values such as 1.5 or 2.5 both get rounded to 2.", but round(2.5) evaluates to 3.0 . (Using Python 2.6.9)

The Python documentation for the round() function states: "... if two multiples are equally close, rounding is done away from 0 (so. for example, round(0.5) is 1.0 and round(-0.5) is -1.0)."
(https://docs.python.org/2/library/functions.html#round)

Dirk Sonnemann  Jul 17, 2014 
Printed Page 108
3rd line of discussion

simply set the //days// attribute to 1 --> simply set the //day// attribute to 1

Anonymous  Aug 23, 2016 
Printed Page 113
5.6 solution

>>>print('This is a test', file= s)
15

Nothing is output under Python 3.8.1

>>>s.write(b'binary data')
>>>

"11" is output

Gregory Sherman   Mar 27, 2020 
Printed Page 134
5th paragraph of discussion

It is true that "itertools.chain()" would not work here, but "itertools.chain.from_iterable()" would do the trick!

Marco Paolieri  Jun 26, 2014 
Other Digital Version 135
Top of page

Recipe 4.14 - Flattening a nested sequence:
Calling flatten('h', type(None)) will lead to infinite recursion since a string is always iterable, even if only one character.
Hence the generator as written cannot be used to flatten a string.

Tom Curnock  Feb 15, 2019 
PDF Page 137
second code example

The second code example shows:

with open('sorted_file_1', 'rt') as file1, \
open('sorted_file_2') 'rt' as file2, \
open('merged_file', 'wt') as outf:

The second open statement should read as follows:

open('sorted_file_2', 'rt') as file2, \


MacBent  Jan 23, 2016 
PDF Page 145
Code after 1st paragraph of Discussion

Chrapter 5, Recipe 5.3. First code example in the discussion section, usage of str.join() method is incorrect.
It is written:
print(','.join('ACME', '50', '91.5'))
A possible solution is to add the strings into a tuple or list:
print(','.join(('ACME', '50', '91.5')))

Thales Mateus Rodrigues Oliveira  Jan 15, 2020 
ePub Page 145
last code block of 2.18

PRINT = r'(P<PRINT>...
NAME = r'(P<NAME>...

Both are invalid regular expressions - need ? between ( and P

Gregory Sherman   Mar 27, 2020 
ePub Page 150
3.1 Solution

"For simple rounding, use the built-in round(value, ndigits) function."

'ndigits' is optional (at least in Python 3.8.1)
The result is an int if the second argument is omitted.

Gregory Sherman  Oct 01, 2020 
ePub Page 151
couple of paragraphs before Discussion

"When a value is exactly halfway between two choices, the behavior of round is to round to the nearest even digit."

This seems to be true for integer rounding in Python 3.8.1, but my testing of floating-point rounding does not follow this pattern

>>> round(1.05, 1)
1.1

>>> round(1.15, 1)
1.1

>>> round(1.85, 1)
1.9

>>> round(1.95, 1)
1.9

>>> round(2.15, 1)
2.1

Gregory Sherman  Oct 01, 2020 
Printed Page 152
the 8th and 10th line of second in-line example

In 8th and 10th line, b'Hello' misspells as b'Hallo'.

Fei Chen  Dec 17, 2016 
ePub Page 166
7.2 solution, second function

The funciton name and the two calls to it do not match.
The function should probably be named minimum(), rather than mininum().

Gregory Sherman  Apr 17, 2018 
Printed Page 182
at bottom of the page

In the book, the function is implemented as:
def unserialize_object(d):
clsname = d.pop('__classname__', None)
if clsname:
cls = classes[clsname]
obj = cls.__new__(cls)
for key, value in d.items():
setattr(obj, key, value)
return obj
else:
return d

The above code actually will error out. It should be defined as:

def unserialize_object(d):
clsname = d.pop('__classname__', None)
if clsname:
cls = classes[clsname]
obj = cls.__new__(cls)
for key, value in d.items():
setattr(obj, key, value)
return obj
else:
return d

The downloaded code is implemented correctly

tony tang  Aug 04, 2016 
Printed Page 190
first code block of 8.6 solution

class Person:
.
.
.
@property
def first_name(self):
return self._first_name

The exact same getter appears in the Discussion, but with the text:
"Don't write properties that don't actually add anything extra like this.:

Gregory Sherman   Mar 27, 2020 
Printed Page 196
5th par. beginning 'To perform a query.'

The following code ...

>>> for row in db.execute('select * from portfolio'):

... the word 'db' should be replaced by 'c'. ('execute' is a method of class cursor,
not the class connect). The rest of the page uses 'db' for a connect and 'c' for a cursor.

The same error occurs again in the next paragraph.

Charles Jardine  Feb 06, 2017 
Printed Page 200
Last code sample on page

The 'unpack_records' function makes use of a variable called 'offset' which is undefined.
The same error is also present on page 202, last code sample.

Johannes Sjögren  Feb 05, 2018 
ePub Page 202
6.11.3 text before the 4th example code in this discussion

The original text """ (e.g., b) """ should be """ (e.g., b'') """
missing two signle quotation marks.

Wen Wang  Jul 10, 2019 
ePub Page 208
8.13 Discussion - second code block

When the downloaded program (implementing_a_data_model_or_type_system/example_clsdec.py) is run,
the following message of unknown origin appears for each of the three tests of the Stock class:

'<' not supported between instances of 'str' and 'int'

Gregory Sherman  Nov 02, 2018 
Printed Page 251
last paragraph of Discussion

You say:

(i.e., the use of a leading underscore could be interpreted as a way to avoid name collision rather than as an indication that the value is private).

In the context of the example I think what you wanted to say was the opposite:

(i.e, the use of a leading underscore could be interpreted as an indication that the value is private rather than as a way to avoid name collision).

Thomas Geppert  May 07, 2014 
Printed Page 252
1st snippet

In the class Person constructor definition, the self.first_name attribute affectation should contain an underscrore as first_name parameter is setting an underlaying private attribute of the class.

eric regnier  Aug 16, 2017 
ePub Page 254
8.6.3 second code example in this discussion

the original codes in book
"""
class Person:
def __init(self, first_name):
self.first_name = name
"""

should be
"""
class Person:
def __init(self, first_name):
self.first_name = first_name
"""

Wen Wang  Jul 10, 2019 
Printed Page 258
bottom

"Python starts withe the leftmost...",
Is seems to start with the rightmost and work its way left and avoid repeating itself. First Base, then B, then A, then C

Mike Sweeney  Feb 22, 2019 
ePub Page 286
first "Discussion" code

>>>print(','.join('ACME', '50', '91.5'))
Under Python 3.8.1, this results in:
"TypeError: join() takes exactly one argument (3 given)"

needs to be:
print(','.join(('ACME', '50', '91.5')))

Gregory Sherman  Mar 27, 2020 
Printed Page 335
Function decorate

Should be
logname = name if name is not None else func.__module__
...
log msg = message if message is not None else func.__name__

In an earlier chapter you discuss how important it is to check for None using, for example, "if x is None" instead of "if not x"

Siva Kumar  Oct 31, 2017 
PDF Page 350
Under solution section.

Under solution is says: make sure that your decorators are applied before @classmethod or @staticmethod..

This should read 'after', not 'before'

Simon Garisch  Jul 05, 2019 
Printed Page 382
Solution

class Person:
def __init__(self, name, age):
self.name = name
self.age = age

should be

class Person:
def __init__(self, name, age):
self._name = name
self._age = age

the underscores for the private class variables went missing (as the @property @name/age.setter use _name and _age).

Anonymous  Apr 25, 2014 
PDF Page 476
method EventHandler.fileno

The method does:

raise NotImplemented('must implement')

But it should instead:

raise NotImplementedError('must implement')

because NotImplemented is not an exception, but a special value used when overloading operators, and NotImplemented is not callable, so the method as implemented actually raises a different exception:

TypeError: 'NotImplementedType' object is not callable

Luciano Ramalho  Oct 25, 2014 
Printed Page 487
CountdownThread class snippet

In the CountdownThread class initialization, self.n is assigned to 0, instead of passing n argument:

class CountdownThread(Thread):
def __init__(self, n):
super().__init__()
self.n = n # instead of self.n = 0


Jesus ALkorta  Dec 13, 2014 
PDF Page 506
second code fragment

For this to become a proper server and an exact functional equivalent of
the first example, the code in echo_client(q) needs to be wrapped in 'while True:'
Otherwise, the server will only process the first 'nworkers' clients and then just hang there doing nothing, because all the worker threads will have exited by then.

Anonymous  Jul 20, 2016 
Printed Page 532
First paragraph, fourth sentence, third word

"socket" is misspelled as "sockect" in the following passage:

"The other sockect is then passed..."

Alexander Reynolds  Dec 18, 2019 
Printed Page 558
last paragraph

"The call to getLogger(__name__) creates a logger module that has the same name as the calling module. "

should be

".. creates a logger object that has the same name as the calling module. "

Hernán J. González  Nov 07, 2019 
Printed Page 585
Bottom (line 4 from bottom)

(Pdb) print n

Proposed solution:
(Pdb) print(n)

marek vetter  Jun 08, 2020 
ePub Page 849,850
last commands of 11.1

>>> resp['headers']
&
>>> resp['args']
both result in:
TypeError: 'method' object is not subscriptable

Gregory Sherman  Aug 20, 2020 
ePub Page 32801
Chapter 6, Data Encoding and Processing - final example in 'discussion' of CSV data (location above is from the Kindle version)

Text states:

Alternatively, here is an example of converting selected fields of dictionaries:

print('Reading as dicts with type conversion')
field_types = [ ('Price', float),
('Change', float),
('Volume', int) ]

with open('stocks.csv') as f:
for row in csv.DictReader(f):
row.update((key, conversion(row[key]))
for key, conversion in field_types)
print(row)

This produces a 'cannot convert string to float' error when I attempt it in either Python 2.X or 3.X

Anonymous  Dec 28, 2014