Learning Python 4th Edition: Recent Corrections

Below are book corrections which were posted after and still appear in the first reprint of this book, dated January 2010. Naturally, most also appear in the first printing (with the exception of a few that were introduced by first printing fixes), and most or all of these were eventually fixed in later reprints.

Be sure to also check the first section of the clarifications pages for additional changes which were applied in reprints.

Update, 10/30/2011: I've stopped adding trivial corrections made in reprints to the list below, in the name of reduced redundancy. For all items recently patched in reprints, including a handful of additional fixes not listed here, please see the confirmed errata list at O'Reilly's site, sorted by submission date. After two years, there have been more than half a dozen printings so far, both with and without changes, and O'Reilly's site does a better job of tagging patches with their fix/reprint date than I can here.



  1. [Jul-7-10] Page 39, paragraph 3, minor typo: delete extra word "of"
    [Fixed in 8/2010 reprint] At the start of the 3rd paragraph, change "For instance, of the following tests" to "For instance, the following tests". (This was read many times by many readers, but missed by us all.)



  2. [Feb-5-11] Page 57, line 3 of last code listing on page, minor typo in comment: "outout"
    Change this line from "...same outout..." to "...same output...", with "output" instead of "outout". Typing too fast here, apparently. This is in an informal comment and is not code, so it isn't too grievous, but it merits a patch in reprints.



  3. [Jul-7-10] Page 58: exec() sentence broken by rewording applied during production
    [Fixed in 8/2010 reprint] On page 58, at the very end of paragraph 2 in the note box near top of page, change "For more on the 3.0 exec form, see Chapter 9." to read "For more on the file interfaces used by the 3.0 exec form, see Chapter 9."

    This was implied in the original admittedly choppy version of this sentence that I submitted (yet another case of copyediting being a bit too aggressive, I'm afraid). Perhaps obvious to many (Chapter 9 covers files, not exec()) but I found myself searching for exec() in Chapter 9 a year later due to the unfortunate rewording of this sentence made during production.



  4. [Nov-5-10] Page 72, line 6: "PyPy" should be "PyPI" (minor typo)
    The title says it all; this sentence refers to the Python Package Index site (PyPI), not the Python in Python project (PyPy). Both are described earlier in the book so this should be obvious to most readers, but it still merits a patch in reprints.



  5. [May-1-10] {first reprint} Page 90, second line on page, comment font (minor formatting)
    The comment text "# iter(G) not required here" should be in italics, like the others are. This comment was added as a patch in the first reprint. It is not present in earlier printings.

    (This item and a handful of others in this list labeled as "{first reprint}" were introduced when fixes for prior errata were applied in the first reprint. Patching is a net improvement, but regrettably, fixing errata can itself introduce new errata, so the benefit has to be weighed against the potential risk, especially if the fix involves changing program code.)



  6. [Jul-7-10] Page 110, 4th bullet item from the bottom: typo, 'X < Y < Z' => 'X < Y and Y < Z'
    [Fixed in 8/2010 reprint] Change "X < Y < Z produces the same result as X < Y and Y < X." to read "X < Y < Z produces the same result as X < Y and Y < Z." The X and the end should be Z, of course, as covered correctly in detail on page 116.



  7. [Jul-7-10] Page 122, last line: octal output shown in Python 2.X form but not stated as such
    On the very last line of this page, in the output tuple ('0100', '0x40, '0b1000000'), the first item is an octal that should be shown as '0o100', not as '0100'. That is, it should have a leading "0o" instead of just a leading "0". As is, the printed value in the book is correct for Python 2.6, but not 3.X; the book covers both but this confused at least one reader as it is.

    The new 3.X format for octals is described in depth in this section, but this specific example was run under 2.6; since the rest of the book is "3.X unless stated otherwise", this should be patched in reprints. Oddly, another 2.6 item snuck in on the next page (an already-posted and patched clarification); these were probably run at the same time.



  8. [May-1-10] {first reprint} Page 135, paragraph 4, line 2: "because because" (minor typo)
    [Fixed in 8/2010 reprint] Change the "because because" to "because" here. This was introduced by a patch applied in the first reprint (a sentence rewording). It is not present in earlier printings. (In the added text, there is also a straight quote in "set's" that should probably be curly, like all others.)



  9. [May-1-10] {first reprint} Page 216, first sidebar code listing, line 2: "#" misaligned (cosmetic only)
    Not a bug and purely cosmetic, but the "# Link to file" comment should be moved 3 spaces to the right so it aligns vertically with the other "#" comments below it. This was introduced by a patch applied in the first reprint (the "anydbm" to "dbm" change). It is not present in earlier printings.



  10. [Jul-7-10] Page 233, second code listing: filename is missing its ".txt" extension
    At the start of the second code listing on this page, change "for line in open('myfile'):" to "for line in open('myfile.txt'):", adding just the ".txt" at the end of the file's name. No idea how the extension was dropped here (or added elsewhere?). Also, if and only if there is space at the very end of the immediately preceding line, add the text "(shown here with a Python 3.X print call)"; minor, but a reader found this confusing when it failed on Python 2.6.



  11. [Jul-7-10] Page 238, 3rd line of page: struct.unpack output shows 2.6 str instead of 3.X bytes
    The code listing in line 3 from page top which reads "(7, 'spam', 8)" should read "(7, b'spam', 8)" with the leading "b" on the string in the middle to reflect Python 3.X behavior, as is shown correctly on page 931 where this example is repeated with further elaboration. Again, the book covers 2.X too, but this is ambiguous as shown. Apparently another case of code run under 2.6 inadvertently (or at least without saying so).



  12. [Aug-1-10] Page 295, middle of 1st sentence in notebox: wording broken by production in QC1
    A year after publication, I still find instances of meaning having been broken badly by edits made after I submitted the final draft to production. Here's the latest: the start of this sentence was reworded to make it refer to a prior section in the book, when it was obviously meant to refer to a section of an external web page. The rewording makes no sense, even on shallow reading.

    To fix, change: "For additional naming suggestions, see the previous section “Naming conventions” of Python’s semi-official style guide, known as PEP 8." to use the original wording as follows: "For additional naming suggestions, see the “Naming Conventions” section of Python’s semi-official style guide, known as PEP 8. ". Also remove the link in this for text "Naming Conventions"; this is about a web page, not about the section of the same name elsewhere in this chapter! As far as I can reconstruct, this error was introduced after copyedit, and first appeared in QC1--far too late to be caught.



  13. [Sep-27-10] Page 301, Table 11-5, row 3 column 3: minor inconsistency in 2.6 print table
    In this row/column, change "myfile.write" to "afile.write", to match the other columns in this row. Not an error since the table is abstract anyhow (and no readers have reported this as confusing), but worth a patch for consistency.



  14. [Jul-7-10] Page 305, end of 2nd code listing: minor typo in comment, "Bad" should be "Bad!"
    Trivial, but inaccurate as is; change the text of just the code comment on the right from "# 2.6: print >> sys.stderr, 'Bad' * 8" to "# 2.6: print >> sys.stderr, 'Bad!' * 8", adding just the "!".



  15. [Jul-7-10] Page 348, bottom line of the second paragraph: minor typo, "cal" to "call"
    Change "to the dict cal for" to read "to the dict call for".



  16. [Jul-12-10] Page 348, 2nd last line of the second paragraph: minor typo, need a comma
    Same sentence as prior item: Change "dictionary comprehensions an alternative" to read "dictionary comprehensions, an alternative" by adding the comma. This reflects a change made in copyedit; the comma was present in the orignal and this seems to read better if present.



  17. [Feb-5-11] Page 354-355, code listing that spans pages: use 3.X I.__next__(), not 2.X I.next()
    A reader noticed that this code listing uses Python 2.X style next() iteration methods, but does not state so explicitly. I'd like to simply add a note to this effect, but in this case that could be confusing, and is probably a cop out: all the other listings in this section use the 3.X style __next__(), and this one should match. This 2.X/3.X difference is stated in note boxes on pages 356, 494, and 712, and mentioned on pages 707 and xxxvi. Since this example did not appear in the prior edition, the 2.X code here must have been run in a 2.X window -- yet another artifact of dual-version coverage.

    To fix, change ">>> I.next()" to read ">>> I.__next__()", adding the leading and trailing double underscores around "next", in all 4 appearances here: lines -4 and -2 of page 354, and lines 1 and 3 of page 355. Be careful to not alter the fonts or the vertical alignment of the "#..." comments to the right in the process. When applied, the full interaction that spans these two pages should look like this:
    >>> L = [1, 2, 3]
    >>> I = iter(L)                # Obtain an iterator object
    >>> I.__next__()               # Call next to advance to next item
    1
    >>> I.__next__()
    2
    >>> I.__next__()
    3
    >>> I.__next__()
    Traceback (most recent call last):
    ...more omitted...
    StopIteration
    


  18. [Jul-7-10] Page 455, start of 2nd last paragraph: minor typo, delete the duplicate "can get"
    Just under header "Bonus Points", change "You can get can get bonus" to "You can get bonus". Present in the original draft, and unnoticed during tech review, editing, and production.



  19. [Jul-8-10] Page 477, paragraph 4: 3.X can use print() instead of sys.stdout.write() in lambda
    While not incorrect, the discussion of printing from within a lambda's expression here, and its application in later examples, is a bit 2.X-biased. It suggests using sys.stdout.write(), which is required in Python 2.X because printing is a statement that cannot appear as an expression. In Python 3.X, though, we can simply use a print() call inside a lambda (and drop the explicit "\n" characters), since printing becomes a function-call expression. On the other hand, the sys.stdout.write form works in both Python lines, and so is more portable. Hence this may be more clarification than correction.

    To avoid confusion, though, reword the current start of this paragraph: "For example, if you want to print from the body of a lambda function, simply say sys.stdout.write(str(x)+'\n'), instead of print(x) (recall from Chapter 11 that this is what print really does)."

    to read as follows, with the "print(x)" and "sys.stdout.write(...)" parts in literal font: "For example, if you want to print from the body of a lambda function, simply say print(X) in Python 3.X (where this becomes a call expression instead of a statement), but say sys.stdout.write(str(x)+'\n') in either Python 2.X or 3.X to make sure it's an expression portably (recall from Chapter 11 that this is what print really does)."



  20. [Jul-8-10] Page 483, question #2: minor typo, "lamba" should be "lambda"
    Change "lamba?" to read "lambda?" at the end of question #2. Probably obvious given that "lambda" appears some eleventy-billion times here, but worth fixing. Python does not yet have a "lamba" feature that we are aware of...



  21. [Jul-8-10] Page 500, middle of 3rd paragraph: minor typo, "how any" should be "how many"
    Just before the header that starts "Emulating zip...", change "decide how any iterations" to "decide how many iterations". Present in the original draft, and unnoticed during editing.



  22. [Jul-9-10] Page 511, paragraph 2 line 5: minor typo, "tuple of four" should be "tuple of five"
    A test function was added to the code but the narrative wasn't updated. Change "a tuple of four function objects" to "a tuple of five function objects". Present in the original draft, and unnoticed during editing and tech review.



  23. [May-1-10] {first reprint} Page 519, first line on page, need a blank line after it? (minor formatting)
    It looks like we need a blank line after this line and before the code listing that follows it. If you need to free up a line for this, delete the "...error text omitted..." code listing line (only) later on this page, since it's mostly superfluous. This was introduced by a patch applied in the first reprint (the footnote added on page 518). It is not present in earlier printings.



  24. [Feb-5-11] Page 539, paragraph 2, line 5, minor typo: "mypath.py" should be "mypath.pth"
    Per a reader's email, at the start of this line, change the filename extension at the end of the path "C:\Python30\mypath.py" so that it reads "C:\Python30\mypath.pth". The required ".pth" file extension is described correctly about a dozen times in this section (and again repeatedly in the start-up details appendix), so most readers will probably get past this; but it's worth patching in this one spot where it was munged.



  25. [Sep-27-10] Page 639, minor output typo at end of 3rd code listing section on page
    Change:
    >>> print(rec.age)
    40
    to:
    >>> print(rec.age)
    45
    This looks like an edition skew, given the changed ages listed; probably obvious to most readers, but worth a fix.



  26. [Sep-7-10] Page 649, first sentence on page, "two lines" should probably be "three lines" (minor ambiguity)
    Change "We’ve added the last two lines here;" to "We’ve added the last three lines here;". This one is debatable, and was written as it was intentionally: three lines were physically added, but this sentence discusses just the two that actually matter (not counting the simple print at the end). Still, this sounds ambiguous enough as is to seem like a typo to some readers.



  27. [Jul-7-10] Page 718 and 719: two lingering 2.X-style raise statements in code examples
    The __getattr___/__setattr__ examples here use Python 2.X raise statements, and were apparently run under 2.6 inadvertently. I'm not sure this qualifies as an error per se, as this book covers both 2.X and 3.X, and the raise difference is spelled out in detail repeatedly in the next part of the book (raising exceptions hasn't really been covered yet in full at this point). Still, this seems potentially confusing enough to merit a change.

    To fix, change the two raise statements in the last code listing on page 718 and the first code listing on page 719, from:
    raise AttributeError, attrname
    raise AttributeError, attr + ' not allowed'
    
    to the following, by deleting the commas and adding parens (keep their indentation exactly the same as it is currently--reprints: please ask me to verify the change if in doubt, as this is program code):
    raise AttributeError(attrname)
    raise AttributeError(attr + ' not allowed')
    


  28. [Sep-27-10] Page 755, line -8 on page, comment in last code listing: dict comps not in 2.6
    Change "# 2.6/3.0 dict comprehension" to "# 3.0 dict comprehension". An unreported minor typo in a code comment only, but worth a fix in reprints. As explained elsewhere repeatedly, the dict comprehension expression is a 3.X addition to the language, not present in 2.6 (though it was also picked up by 2.7 after book published, as explained in the book notes at this site).



  29. [Oct-27-10] Page 793, last 2 lines on page, output lines missing in code listing
    Somewhere along the way, we seem to have dropped 2 important output lines at the end of this listing (alas, this appears to have been propagated across multiple editions of the book). The text and code comments here and elsewhere describe __setattr__ behavior correctly, but the listing is misleading as is. To fix, change the very last two lines on this page which read:
    >>> x.job = 'trainer'              # Runs __setattr__ again
    >>> x.job                          # Defined: no __getattr__ call
    
    to the following, adding the 2 new output lines in non-bold font, and retaining the original spacing of the "#" comments on the right:
    >>> x.job = 'trainer'              # Runs __setattr__ again
    set: job trainer
    >>> x.job                          # Defined: no __getattr__ call
    'trainer'
    
    (Thanks to a reader in Taiwan for finally reporting this item.)



  30. [Jul-7-10] Page 803, paragraph 2, end of line 3: minor typo, "Object" should be "Other"
    We need to replace "Object" with the actual class name "Other" in the sentence that ends on this line (an apparent slip of the virtual tongue). Change "it would update Object, not Spam! In this" to read "it would update Other, not Spam! In this". Note: keep in mind that the built-in universal superclass, implied in 3.X and explicit in 2.X, is named lowercase "object", not "Object"; this may have added to the confusion of a few readers who reported this typo.



  31. [Jul-7-10] Page 805, end of second-last line on page: minor typo, "next part" to "final part"
    Change "to coding decorators in the next part of this book. As" to "to coding decorators in the final part of this book. As". (The next part of the book is exceptions, not advanced topics.)



  32. [Jul-7-10] Page 813, very first line on page: minor typo, "Print" to "print" in error message
    Change "Print(Spam.count)" to "print(Spam.count)" at the start of the very first line on this page. This is a code line which is part of a generated error message; it's shown correctly everywhere else here so this should be obvious, but merits a fix (MS-Word's auto-correction had a nasty tendency to uppercase code like this).



  33. [Jul-7-10] Page 820, exercise numbers broken in production: #3 and #4 should be #8 and #9
    Exercise numbering on this page was broken during production: numbers 3 and 4 here should be renumbered to be 8 and 9, as per my original final draft. Probably obvious to most readers, and these are numbered 8 and 9 correctly in the solutions appendix, but it's worth noting and fixing in reprints.



  34. [Jul-7-10] Page 898, 2nd bullet item on page: minor typo: "is' should be "its"
    Another typo missed by all: At the end of the "Decoding" bullet's first line, change "into is character string" to "into its character string".



  35. [Sep-27-10] Page 944, last line of 2nd paragraph on page, minor text typo (broken by production)
    Change "(you can the superclass in 3.0 too," to "(you can list the superclass in 3.0 too,". This was broken by an edit made during production; in my final draft, the original version read "(you can in 3.0 too," which was arguably ambiguous, but not grammatically incorrect!



  36. [Sep-27-10] Page 1001, last line of paragraph 4, minor typo: "in" should be "is"
    Change "class in not included in *args." to "class is not included in *args.". This typo was present in final draft, but missed by all proofreaders (including me).



  37. [Sep-27-10] Page 1132, lines 5-7: exception traceback gives prior 2.X version code+output
    In the solution to the problem #3 of Part VII, the last 3 lines (lines 5-7 from the top of this page) should be changed from:
        raise MyError, 'world'
    hello: world
    Got hello world
    to read as follows:
        raise MyError('Spam!')
    oops.MyError: Spam!
    Got  Spam!
    No idea how this slipped through the cracks (other than that this is a 1100-page book written on a typically crazy schedule, of course...). Most readers should be able to spot this by this point in the book, given that the error text and correct listed code don't match, but it merits a reprints patch.



  38. [Aug-1-10] Page 1144, in the index "distutils" is misspelled as "disutils"
    The title says it all: add a "t" to fix the spelling. It's spelled correctly everywhere else in the book.


Older corrections: see the first printing corrections page

Back to this book's main updates page



[Home page] Books Code Blog Python Author Train Find ©M.Lutz