The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

>>but still sometimes things escape notice, so thanks for pointing out those for future correction!

What does "future" mean in this context? I posted dozens of corrections a full 2 years ago (which in the tech world is equivalent to millennia). Since then, many other readers have re-discovered many of them, posting their findings on this forum (and others caughts errors I didn't catch).

I understand that the timing of a second printing depends on too many factors, but producing a corrected ebook should not be that challenging. Obviously a new ebook should not be generated every single time a new typo is spotted -- error corrections should be batched. But still, 2 years?
Hi Vern,

Thanks for your kind words. I have finally written up the remaining corrections/suggestions. Given below are errata on chapters 15 to 24, along with a few stray ones from earlier chapters that I didn't catch before.

This time I also have a couple of questions! They are both connected to points I mention below in the relevant comments.

1) p. 202: you say that a module function has the functionality of a class method. Could you please show this in an example, preferably using the the total_area function discussed on pp. 192-193?

2) p. 219: why doesn't "__init__" need to have a line that says "self.master = master"? Maybe Frame has a variable by that name?

In closing, another question, but of a different kind: when the 2nd printing comes out, do people (like me) who bought the 1st printing get a free PDF from Manning?

Alex Gezerlis


p. 31 "Other special attribute methods permit": this should say "Other special method attributes permit".

p. 31 "when you’re ready to move on to the chapters in part 4 [...] before you move on to the chapters in part 4": the material covered in chapter 3 is more or less equivalent to the topics that are introduced in part 2. Part 3 is completely new stuff, so both of these references should mention "part 3", not "part 4".

p. 140 "Fortunately, the directory where the script is is appended as the first string in sys.path.": given OED's definition of append ("3. To add in writing by way of supplement or appendix.") I think it would be more appropriate to use here the word "prepend" -- "Chiefly Computing. trans. To add at the beginning, to prefix, prepose; esp. to add or append (a character, string, file, etc.) at the front of an existing string, file, etc.".

p. 144 "This is done here in the print statement.": this should say "in the print function call.".

p. 164 "print("A line from the print statement")": this should say "print("A line from the print function call output")".

p. 188 "than the previous print statement": this should say "than the previous print function call".

p. 188 "in the same manner as local method function variables": this should say either "in the same manner as local method variables" or "in the same manner as local function variables".

p. 189 "with one call on the circle class": this should be capitalized, "Circle".

p. 189 "Then, calls to circle would work with": similarly, "Circle".

p. 190 "make a direct call to it as a normal Python": I guess this was supposed to be "make a direct call to it as a normal Python function".

p. 190-192 There are six instances of pi appearing as 3.1415899999999999 and one as 3.140000000000001. These should be 3.14159 and 3.14 respectively.

p. 192 "If you want to change the value of a class variable, access it through the class name, not through the instance variable self.": This is the truth, but it is not the whole truth: we can change the value of a class variable through the instance variable self if we use self.__class__. In your example this would be something like c1.__class__.pi = 3.1 (or c2.__class__.pi = 3.1).

p. 193 "circle module: contains the Circle class.": this should say "circle_cm module: contains the Circle class.". The circle module was defined on the previous page.

p. 194 "You can use cls instead of self.__class__": I don't really understand this. Since "total_area" does not take "self" as a parameter, we would not be able to use "self.__class__" even if we wanted to. Perhaps what you meant to say was that in contradistinction to the case of the static method shown above, "You can use cls instead of Circle".

p. 195 "you can see in the bolded code in the Circle and Square classes.": there is no bolded code in these classes.

p. 195 "a method that isn’t defined in the base classes but is defined in the superclass": the word "superclass" and the phrase "base class" are synonyms. You probably meant to say "a method that isn’t defined in the derived classes but is defined in the superclass".

p. 196 "Inheritance allows an instance to inherit attributes of the class.": the way it is right now, this sentence is too vague. Perhaps you meant to say "Inheritance allows an instance to inherit attributes of the base class.".

p. 198 "What specifically happens is that _classname is appended to the variable name": as I pointed out above in connection with p. 140, here it is probably more appropriate to say "prepended" instead of "appended".

p. 198 "If someone wanted to, they could access the value.": it is perhaps worth mentioning here that (in keeping with what is discussed in the appendix, on p. 317) one could print the private variable from outside by saying "print(m._Mine__y)".

p. 199 "93.200000000000003": the output in Python 3.1 is "93.2".

p. 200 Fig. 15.2: In the bottom row, the third from the right box says "Private instance" but it should say "Private instance variables".

p. 200 Fig. 15.2: In the top row, the second from the right box says "Superclass class variables" but it should say "Private superclass methods".

p. 201 "(but use SC.siv for assignment)": this appears on the line that defines self.siv. It is quite baffling: in all other cases when you say "use ClassName.variable for assigment" you do that for class variables, but siv is not a class variable, it's an instance variable. If this is changed, its output should also be changed. Also, you do not say "use SC.scv for assigment" when you define the superclass class variable scv.

p. 201 "self.iv = 'instance variable: self.xi'": I see no reason why this should be "self.xi" and not "self.iv". If this is changed, then it should also be changed in the output, on p. 203.

p. 201 Next to "variable print(lv)" you have an arrow that says "Instance variable". This should say "Local variable".

p. 202 Next to "print(self.__pm())" you have an arrow that says "Private module". This should say "private method".

p. 202 Next to "print(self.scv)" you have an arrow that says "Superclass variable through instance". This should say "Superclass class variable through instance".

p. 202 "the module function mf, (which, as described in a previous section, we can use to provide a class method functionality)": I don't believe this was described in a previous section. The only way we have seen of getting a class method is by using the @classmethod decorator.

p. 203 "two methods M and M2, along with the mangled names of the private method __PM": these names should be changed to "m", "m2", and "_pm", respectively.

p. 203 "superclass method SM. It also contains the mangled names of private superclass method __SPM and private superclass class variable __spcv": these names should be changed to "sm", "_spm", and "_pscv", respectively.

p. 203 "superclass method: self.SM()": this should be changed to "superclass method:".

p. 207 "the inheriting class behaves like a synthesis of its own definitions and all of its ancestor’s definitions.": this needs an extra "s", i.e. "ancestors's".

p. 207 "the class definitions y look like this": the "y" should be removed.

p. 217 "the corners of a 2?×?2 grid [...] 2×?2": both of these should be "2x2".

p. 221-222 "QT is a rich and powerful GUI framework and also has QT Designer": both of these occurrences of "QT" should be changed to "Qt".

p. 219 "command=self.master.destroy": you do not explain why you need to do this instead of "self.destroy" (this does not kill the main window). This is connected to the fact that when you create the label and two buttons you do not explain why you say "Label(self" and "Button(self", though you could be saying (to be consistent with the original form of the example) "Label(self.master" and "Button(self.master". While we're on this subject, shouldn't "__init__" have a line that says "self.master = master"? On the other hand, right now it doesn't and it seems to be working just fine without it.

p. 219 "because increment_counter is now an instance variable": this should say "because count_value is now an instance variable".

p. 226 "match many different specific strings..": one of the two periods should be removed.

p. 227 "is given in the appendix at the end of this book": this should say "is given in the Python documentation".

p. 227 "not with embedded -
sequences": I think the "-" should be deleted.

p. 229 "let’s assume for right now that that first names": one of the instances of "that" should be removed.

p. 230 "( (?P<middle>([-a-zA-Z]+)))?": perhaps there is an extra set of parentheses here. "( (?P<middle>[-a-zA-Z]+))?" would work just as well, and would be consistent with the other cases. If you do change this here, you should also change it on p. 231.

p. 231 "print('Name:', firstname, middlename, lastname,' Number:', phonenumber)": you probably used this indentation for page-setting reasons. However, given where it's currently placed, you're trying to access the "firstname", "middlename", "lastname", and "phonenumber" variables even when "result == None".

p. 235 Figure 18.1 has two instances of "constants.pi". Given the discussion in the text, as well as Figure 18.2, I think it's obvious that this should say "".

p. 236 One of the leaves in Figure 18.2 says "__init.py__": this should be "".

p. 238 "These two lines are printed out by print statements in the files": this should say "print function calls".

p. 239 "print "version is", version": this should be "print("version is", version)".

p. 239 "print h()": similarly, this should be "print(h())".

p. 243 "We have any easy way of finding out": this should say "an" instead of "any".

p. 245 "The issubclass function is only for class types.": this should be in the same font as the text (with the exception of the name "issubclass".)

p. 248 "Color: R={0:d}, G={1:d}, B={2:d}": I don't think you've shown this way of using the format method before (i.e. ":d" inside the positional parameters).

p. 249 "all of which are defined in the reference appendix": this should say "in the Python documentation".

p. 251 "implementing a full-list emulation class": this makes it seem like you're interested in an entity called a "full list". In reality, you're interested in a "list-emulation class" which is full, so "implementing a full list-emulation class".

p. 252 "special function attributes": you list this in your errata. I believe this isn't necessarily wrong. It's also used in "Dive Into Python 3" (section 17.25) and in "Core Python Programming" (exercise 14.11). (The official documentation isn't much help here, since it calls these "special method names".) If you do think it's an erratum, then you should also change it on p. 256: " all of the appropriate special function attributes".

p. 253 "The accesses of elements of x in the print statement": this should say "in the print function call".

p. 253 "The last line uses __getitem__ to unpack the first four items in x and then pack them into the variables a, b, c, d, and e, respectively.": first, the unpacking and packing does not take place in the last line, but in the second to last line. Second, x.elements has five elements, which are then packed into the five variables a, b, c, d, and e, so I don't understand why the text says "the first four items in x".

p. 255 "super().__init__(initial_list)": this is the first thing you do in the __init__ method of class TypedUserList. On the other hand, on p. 254 that same call is the last thing you do in the __init__ method of class TypedListList. Is there a reason for this discrepancy? Since the rest of the body of the __init__ method (in both cases) simply checks for validity, I suppose it makes more sense to call the parent's constructor at the end of the checks.

p. 257 "Note that the type of the class spam is 'type'.": this should say "Spam".

p. 257 "Spam = type("Spam", (object,), {'__init__': init, 'show': show})": given that this is a book on Python 3, all the classes shown up to this point were new-style classes. As a result, all classes inherit from "object". However, this is the first point in the book where this fact is shown . Perhaps this warrants a short explanation.

p. 257 "and the type of spam is still 'type'.": this should say "Spam".

p. 257 "def __init__(cls, name, bases, methods):" and "type.__init__(cls, name, bases, methods)": you have described above that the last item is a dictionary of attributes, not methods. Thus, it would be best in both cases if the last argument was renamed to something like "dict" (like on p. 25smilie.

p. 261 "The abstractmethod function sets a function attribute": perhaps this was supposed to be "The abstract method sets a function attribute"?

p. 262 "def getx(self): # read only": I can't help but think that this comment belongs with "def readx(self):". getx is a normal method, so there's no real reason to explain that it doesn't write. What is new in this example is that readx is an abstract property which is read-only (and also that getx and setx can be combined to provide a read-write property).

p. 271 "There are number of test asserts in TestCase": I think you're missing an "a".

p. 272 "Let’s assume that we changed the value of the __getitem__ test so that it would fail:" the first two lines of the output following this sentence only appear if you give the -v option.

p. 272 "self.assertEqual(self.aTypedList[1], 3)": this is part of the assertion error output. It is consistent with the code sample you have provided, but not with the text in Listing 21.3. There you say "self.assertEqual(self.a_typedlist[1], 2)", i.e. after the change from "2" to "3" the variable would still be called "a_typedlist", not "aTypedList".

p. 272 "This is done most easily by using the TestSuite, TestLoader, and TestRunner classes.": the word "TestRunner" should be "TextTestRunner".

p. 272 "unittest.defaultTestLoader().loadTestsFromTestCase(TestTypedList)": you say "defaultTestLoader()" but you also mention that defaultTestLoader is an instance. In that case shouldn't the parentheses be missing?

p. 275 "" and "next(an_iterator)": these are not mentioned anywhere else in the book. If they're here for the sake of completeness, then other things like string formatting and metaclasses also belong here.

p. 276 "infile = open(filename, "rb")": for this to be consistent with the code shown in Listings 22.2 and 22.3, it should say "infile = file(filename, "rb")".

p. 277 "print "%d cents contains %d quarters" % (cents, quarters)": Listings 22.2 and 22.3 use "%s". At least one of these needs to be changed.

p. 277 "getting a string from the user, opening a file, reading from the file, comparing the contents of the file to a string, appending a string, handling errors, and so on.": I cannot see where the contents of a file were compared to a string, or where the code appends a string.

p. 277 "there is no long an integer type in Python 3.x": the word "an" should be removed.

p. 281 "Migrating the code Python 3 is probably the ideal long-term solution": this should say "to Python 3".

p. 287 "This section surveys your options when you need to do something that isn’t in the standard library.": this section ends with that sentence, so it doesn't really survey such options.

p. 288 "The current system uses distutils, which is a module in the standard library.": here you call distutils a "module", but on p. 145 you had called it a "package".

p. 288 "followed by the location you want use": this should say "you want to use".

p. 289 "Csmilieocuments and Settingsvernlib": the Linux example showed the libraries as being at "/home/vern/lib/python" so shouldn't the Windows example also end with "python"?

p. 291 "The specification calls for the use of a connection object [...] is a connection object. Getting a connection object requires [...] which will direct the connection object to parse": looking at PEP 249, it looks like "connection" should be capitalized.

p. 291 "or the use of cursor objects to manage [...] The second step is to create a cursor object": similarly, I think this should be "Cursor".

p. 291 "calling the connect function with the name of file that will be used": this should say "the name of the file".

p. 293 "Cursor = conn.cursor()": you probably capitalized this to make it look slightly different from the cursor method. However, in the other rows of this table (as well as in the examples in the text) you simply call it "cursor".

p. 299 "to print to StringIO object": this should say "to print to the StringIO object".

p. 301 "we need to get the PATH_INFOsmilieATH_INFO from the request": I think this should be simply "PATH_INFO".

p. 333 The entry on shelves has a sub-entry on "key membership (has_key)". This should either be changed to "key membership (in)" or it should removed.
Dear Vern,

I am copying below a newer list of errata, focusing on chapters 8-14 (along with one correction from chapter 3, which I didn't notice the first time around). I have collected more errata for chapters 15-24, but I haven't found the time to type those up yet.

I have also posted a very positive review of "The Quick Python book" on I didn't mention the errata there, since I know that it is very common for a first printing of a technical volume to have many minor errors. Once again, congratulations on writing a great book!

Alex Gezerlis


p. 24 "clear, copy, get, has_key, items, keys, update, and values": as you discuss on p. 277, "has_key()" is not part of Python 3, and has been replaced by "key in dict".

p. 92 "variable is set to be the first element of sequence, and body is executed; then, variable is set to be the second element of sequence": you should change either the for loop to say "for variable in sequence" or the two instances in the discussion of "variable" to "item".

p. 93 "a sequence of integers from 0 up to 10000000": this should say "a sequence of integers from 0 up to 10000000-1".

p. 93 "the value of range(5,3) is an empty list": this should say "the value of list(range(5,3)) is an empty list".

p. 94 " as normal with the next item. .": one of the two periods should be removed.

p. 96 "A block containing a single line may be placed": this is not clear to me. Perhaps you want to say something like "A single-line block" or "A block of statements placed on a single line".

p. 100 "See the appendix for more details on precedence.": this should be "See the Python documentation for more details on precedence.".

p. 101 "let’s look a small sample that": this should say "let’s look at a small sample that".

p. 101 "format count, word_count, char_count))": this should be "format(line_count,word_count, char_count))".

p. 104, 105 The last prompt at the bottom of the page shouldn't be there.

p. 105 "In the first line of the function, you specify definition variable names": I think this was supposed to be "In the first line of the function definition, you specify variable names".

pp. 111-112 There are five occurrences of the number 273.14999999999998. In all five cases Python 3.1.1 gives me 273.15. This is due to Issue 1580 ("Use shorter float repr when possible").

p. 117, 118, 127 There are three occurrences of the number 3.1415899999999999. As above, these should be 3.14159.

p. 118 "you can also specifically ask for names from a module to be imported in such a manner that you don’t have to prepend it with the module name": this should say "prepend them".

p. 119 "But if a list of names called __all__ exists in the module (or the package’s, then the names are the ones imported, whether they begin with an underscore or not.": I think this would be considerably more clear if it said "then the names given in this list are the ones imported".

p. 121 "See the section on environment variables in the appendix for examples of": this should say "in the documentation".

p. 121 "You also may have to move or create a mymodules.pth file": the file shown in Listing 10.2 is called "myModules.pth", so I guess one of the two has to be changed.

p. 123 "long, list, tuple, cmp": "long" and "cmp" should be removed, as they are not part of Python 3.

p. 126 "exit local: {'y': 2, 'x': 2, 'w': 6}": since your function actually prints list(locals().keys()) the output will not be what you show but "exit local: ['y', 'x', 'w']".

p. 126 "cmp" should not be part of the output of dir(__builtins__).

p. 127 "Those ending in Error and System Exit": perhaps this was supposed to say "Those ending in Error and Exit".

p. 130 "hello": this is described as the "output of". However, the output of is "this is our first test script file".

p. 132 "which is True by default (action=store_false)": there should be quotation marks around "store_false".

pp. 138-144 In all the listings you write "#! /usr/bin/env python3.1" which based on what you said on p. 135 is probably because Python 3.1 is not the default on your system. However, when you run the scripts corresponding to Listings 11.10, 11.11, 11.13, and 11.14 on the command line in every single case you use python instead of python3.1. If this is because throughout the chapter you would like to simply use python on the command line, then for the sake of consistency I guess you should change all the occurrences of "#! /usr/bin/env python3.1" to "#! /usr/bin/env python" (obviously, excluding the note on p. 135 where you explain what to do if python3.1 is not the default).

p. 139 "This UNIX shell will find all": I think it's kind of excessive to call that one line a "UNIX shell". Perhaps "This script when run on a UNIX shell will find all".

p. 142 "import sys, string, optparse": it's not obvious to me that you need to import string here.

p. 151 "The arguments to os.path.join need not be single a directory or filename": this should say "need not be a single directory or filename".

p. 152 "os.path.commonprefix(path1, path2, ...) finds the common prefix (if any) for a set of paths.": this shows commonprefix as taking more than one positional arguments. Also, the use of the word "set" in this explanation may be misleading. The Python documentation shows commonprefix using a list, but I just checked and one can use (), {}, or [], as long as it's all one argument, i.e. os.path.commonprefix([path1, path2, ...]), etc.

p. 155 "'a.tmp', '1.tmp', '7.tmp', '9.tmp', 'registry.bkp.old']": this line should start with a "[".

p. 156 "See the appendix for the details of its use.": this should say "See the documentation for the details of its use."

p. 156 "to all the directories contained in the top parameter.": since you introduce os.walk by writing os.walk(directory, topdown=True, onerror=None, followlinks=False) I guess this was supposed to say "the directory parameter".

p. 157 "See the appendix for details.": similarly, this should say "See the documentation for details.".

p. 158 "os.makedirs": to be consistent with the rest of the table, this should say "os.makedirs(path)".

p. 158 "os. walk(path)": this should say "os.walk(path)".

p. 158 The table should also include an entry for os.remove(path).

p. 162 "myfile.write("Hello")": in all previous examples "myfile" has been a filename, so it might be confusing to the reader to use it here as a file object. Perhaps it would be best to say "file_object.write("Hello")".

p. 166 "a C double float": I don't think this terminology is widespread. Most people would say "a C double" or if you want to make the connection with the precision of the floating point, then "a C double-precision float" or "a C double -precision floating-point number".

p. 169 "contains function sole, save, show": this should say "functions".

p. 169 "if _sole_mem_cache_d.has_key((m, n, t))": similarly to what I pointed out above in connection to p. 24, this should be changed to "if (m, n, t) in _sole_mem_cache_d".

p. 169 There are three instances on this page of opening a file with "r" and "w" that should be "rb" or "wb", respectively. Similarly, there are two instances of this on p. 168 and two instances on p. 167.

p. 178 "from the __builtin__ module": this should say "from the __builtins__ module".

p. 179 "no exceptions are thrown to be caught by the try statement": I guess here you meant to say "no exceptions are thrown to be caught by the except clauses".

p. 179 "Nothing else occurs.": you also have a "finally:", so the "finally_body" will also be executed.

p. 180 "the line except exception_type, var:": as you show on the previous page, and as explained in PEP 3110, in Python 3 in this context we don't use the comma, but use "as" instead, which means that this should be "the line except exception_type as var:".

p. 181 "(error.args[2],": the "(" at the beginning should be removed.

p. 181 "if __debug__ is false": this should say "False".

p. 182 "def save_to_file(filename) :": this isn't an erratum per se, but for the sake of consistency you should probably follow PEP 8's recommendation to "avoid extraneous whitespace [...] Immediately before a comma, semicolon, or colon".

p. 184 "return function, (x, y, spreadsheet)": given what you say in the preceding discussion, I guess this should be "return function(x, y, spreadsheet)".

p. 185 "combined with a context management (in this case a file object)": given the terminology you've introduced, this should probably say "a context manager".
Dear Vernon,

I recently started reading "The Quick Python Book, Second Edition" and I've been enjoying it quite a bit. I have read the first 7 chapters and have spotted the following typos/errata. I plan to upload more of these after I've worked through more chapters.

Alex Gezerlis


p. 16 "all the members that belong an object or module": I think this should be "all the members that belong to an object or module".

p. 17 "where we’ll make a quick survey of Python the language": I think this should be should be "where we’ll make a quick survey of the Python language" unless you mean this in contradistinction to "Python the snake" smilie

p. 20 "In the preceding code, variable x is assigned to a complex number": I think it is more appropriate to say "In the preceding code, a complex number is assigned to variable x".

pp. 21-22 One of the elements in the examples used for lists and tuples is "3L". You have not mentioned the L before, and judging by table 22.1 on p. 275 this seems to be a leftover from the previous edition.

p. 23 "This is a triple double quoted string, the only kind that can contain real newlines.": I don't get this. I just tried a triple single quoted string with real newlines and it works just fine. You also point this out on p. 39.

p. 24, 43, 100 The last prompt at the bottom of the page shouldn't be there.

p. 28 "try-except-finally-else": given the logical structure, as well as common usage, I think it makes more sense to say "try-except-else-finally".

p. 30 "<module 'wo'>": as shown in your other example on p. 118, this actually says something closer to "<module 'wo' from ''>". Incidentally, the index does not have an entry on "imp".

p. 46 "You create a listd": the "d" at the end should be removed.

p. 47 "Instead, this return: an empty list": perhaps the first colon should be replaced by an "s"?

p. 50 'x=["life","Is","Enchanting"]: the "s" in "Is" should not be in italics.

p. 54 "del(x[0])": this is inconsistent with what you've shown on pp. 49-50, i.e. the del statement is a statement, (not a method) so we say "del x[0]" not "del(x[0])". This works, however, probably because it is read as "del (x[0])".

p. 59 "to absorb any number elements not matching the other elements": I don't understand this. Perhaps you meant to say "any number of elements"?

p. 65 "The ASCII character set, which is the character set used by Python": this seems to be contradictory with what you say on the next page, i.e. "all strings in Python 3 are Unicode strings". For what it's worth, on my system if I "import sys" and then do "sys.getdefaultencoding()" then Python 2.6.4 returns "ascii", while Python 3.1.1 returns "utf-8".

p. 68 "Sometimes it’s useful to permit the last field in a joined string to contain arbitrary text, including, perhaps, substrings that may match what split splits on when reading in that data.": I don't understand what you mean by "last field in a joined string". What I do understand from your example is "the last element in the list that split returns".

p. 68 "Exceptions are explained in chapter 14, “Reading and writing files.”": I guess this was supposed to say chapter 14, "Exceptions".

p. 69 "import string": this should be preceded by a prompt, ">>>import string".

p. 69 "Strips of all dots": this should say "Strips off".

p. 72 "The first line uses maketrans to make up a translation table": maketrans appears on the second, not the first, line.

p. 72 "checks to see if they can be found in the table given as the second argument": in "x.translate(table)" the table is given as the only argument, so this should say "given as the argument".

p. 74 Here there is an erratum in the errata list. You say "string.uppercase", "string.lowercase" and "string.letters" should be replaced by "ascii_string.uppercase", "ascii_string.lowercase" and "ascii_string.letters" while in reality they should be replaced by "string.ascii_uppercase", "string.ascii_lowercase" and "string.ascii_letters".

p. 74 "usually the existing string methods is simpler and easier": this should say "are" instead of "is".

p. 76 "You can also use the positional parameters.": this sentence is at the end of a subsection on positional parameters, right before a subsection on named parameters. Thus, I think you meant to write "You can also use named parameters.".

p. 83 "6.2800000000000002": this is the output that I get using Python 2.6.4. Python 3.1.1 gives me simply "6.28".

p. 86 "del(x[key])": as before, the example you show is not consistent with the use of the del statement you showed in the main text.

p. 86 "For a complete list, see the appendix or refer to the official Python documentation.": I guess this should be "For a complete list refer to the official Python documentation.".

p. 87 Table 7.2 contains a line on "bytearray" though you have not said anything about this sequence in the main text.

p. 89 "return(result)": again, throughout the text you mention the return statement, so writing it like this might be misleading.
The story is a little more complicated than that. "off of" is closer to a "non-error", see:

"For most Americans, the natural thing to say is “Climb down off of [pronounced “offa”] that horse, Tex, with your hands in the air”; but many UK authorities urge that the “of” should be omitted as redundant. Where British English reigns you may want to omit the “of” as superfluous, but common usage in the US has rendered “off of” so standard as to generally pass unnoticed, though some American authorities also discourage it in formal writing. But if “onto” makes sense, so does “off of.” However, “off of” meaning “from” in phrases like “borrow five dollars off of Clarice” is definitely nonstandard."

Manning is an American publisher, after all.

The OED entry on "off" (subscription needed) includes examples of Shakespeare, Mark Twain, and T. S. Eliot (among many others) using "off of", though the definition itself does say:

"b. Followed by of. In later use only colloq. (nonstandard) and regional."

An amusing tidbit is the following OED web page:

which contains the phrase "Following the switch off of the previous site".
>> * I'm also pretty sure Erlang doesn't use it, though it does use message passing

Anthony isn't implying that Erlang uses MPI. The complete context is:

"another paradigm is CSP (Communicating Sequential Processes)[CSP], where threads are conceptually entirely separate, with no shared data but with communication channels that allow messages to be passed between them. This is the paradigm adopted by the MPI (Message Passing Interface) [MPI]environment commonly used for high-performance computing in C and by the programming language Erlang[Erlang]."

Thus, the meaning of this is that Erlang also adopts the CSP paradigm. Of course, the fact that you misread it (I admit when I was first going over that section I had to re-read this phrase to get it) does perhaps point at a problem with clarity.

>> * MPI is also commonly used for HPC in C++ (see, e.g., Boost.MPI).

There are bindings for many other languages, but the official bindings are nowadays only Fortran and C. The C++ bindings are now deprecated, but of course one can get their functionality through Boost.MPI. In other words, I agree that Boost.MPI deserves a mention, but I wouldn't say "e.g.": Boost.MPI is the only C++ option.
Dear Anthony,

I've now finished reading chapter 4 as well.

I'm at the point now where "Chapter 11 Reference" could come in handy (BTW shouldn't "Chapter 11" be "Appendix B", and similarly "Chapter 12" --> "Appendix C"?). In that regard, I've found your documentation for just::thread very useful (e.g. packaged_tasks and futures have a member function called "get_future()", but futures have a member function called "get()"smilie.

Some of the points I mention below were also mentioned in an older thread, but (apparently) they haven't been addressed.

Another point: in a number of places (over 20) in the book I noticed that you use "> >", i.e. you leave a space between two consecutive >'s in templates. Right angle brackets are now implemented in both GCC and VC10, so since this is a C++0x book I guess the old usage isn't necessary.



p. 69 "data_queue.push(data);" (inside push()): this should say "data_queue.push(new_value);".

p. 69 "data_cond.wait(lk,[this]{return !data_queue.empty();});": when you repeat this line on p. 70 you have removed "this" from inside "[]". I think that you should either explain it on p. 69 and repeat it on p. 70, or you should simply remove it from p. 69.

p. 69 "can be copied almost verbatim from the stack example in listing 4.4": this is in chapter 4, and chapter 4 discusses a threadsafe queue, not a stack. I think you meant to say "in listing 3.5".

p. 70 "std::queue<T> data_queue;": the letter "T" is showing up in bold, for no good reason.

p. 70 "data_queue.push(data);" (inside push()): as in the case of p. 69, this should say "data_queue.push(new_value);".

p. 70 "if(data_queue.empty)" (inside try_pop()): this should say "if(data_queue.empty())".

p. 70 "bool try_pop(T& value)": this function returns false if it could not retrieve a value, but it should return true otherwise, i.e. you should add a line saying "return true;".

p. 83 "std::async(¶llel_quick_sort<T>,std::move(lower_part)));": here you explicitly mention the template parameter T, but in the next (directly recursive) call you don't. Was this intentional? (This question is also relevant to the calls in the sequential version of the code on p. 82)

p. 90 "and we change to the verifying_pin state": the verifying_pin class has not been defined (or even declared).
Dear Anthony,

I've now finished the third chapter and am copying below a number of errata/suggestions.

As before, I would appreciate it if you could respond to my point on p. 29, from the earlier post.

Alex Gezerlis


p. 39 "class some_data" does not contain any data. This makes its name a misnomer, and may obfuscate the entire example (unless the reader imagines some data being in it).

p. 45 "Listing 3.5: A class definition for a thread-safe stack": this is exactly the same name you gave to Listing 3.4.

p. 51 "unsigned previous_hierarchy_value;": this is inconsistent with the definitions of "hierarchy_value" and "this_thread_hierarchy_value", which are "unsigned long".

p. 53 "Listing 3.9: Locking two mutexes with lock() in a comparison operator": Listing 3.6 has the same description but with "std::lock()" instead of "lock()".
Dear Anthony,

As promised, I have finally started reading your book in earnest. I am mentioning below a few minor issues that I have spotted in chapters 1& 2.

Only a few of these points are technical in nature. I would appreciate your feedback on my comment on p. 29.

I hope these are helpful.

Alex Gezerlis


p. 21, 27 "void func(int&);" in both cases this should be "struct func;", since otherwise the two lines "std::thread t(func(some_local_state));" (p. 21) and "scoped_thread t(std::thread(func(some_local_state)));" (p. 27) would not be valid.

p. 26 "The move support in std::thread": the word "in" should be in the regular font.

p. 29 "accumulate_block()(block_start,last,results[num_threads-1]);": I'm a little confused here. You used a similar function object as the first argument to the std::thread constructor: "accumulate_block<Iterator,T>()", though in that case you explicitly mentioned what the template parameters were. I don't understand why you aren't doing the same thing in the second case. It is my understanding that template argument deduction only works for function templates, but operator() in this case is an ordinary member function (of a class template).

p. 30 "we can wait for all the threads we spawned with std::for_each (#10), like in listing 2.8": this *is* listing 2.8. I guess you meant to say "like in listing 2.7".

p. 30 "you could of course pass in an identifying number, such as the value of i in listing 2.8": ditto.
> Typo in the last paragraph just before subsection
> 4.2: extra "the": "If the waiting thread is only ever
> going to wait the once"

This isn't a mistake. Here's what the OED has to say:

once, adv., conj., adj., and n.

11. Preceded by this or that (or occas. the): on this (that, etc.) sole occasion. Sometimes also with for.

1603-25 Successors of Edw. IV in T. E. Evans Old Ballads (1784) II. xxv. 152 But when the duke of Buckingham..Began a quarrel for the once.
1666 G. TORRIANO Proverbial Phr. 118 To whine and lament ones misfortune, of being short of money, and that for the once, for to prevent any body that should offer to borrow.
1887 T. DARLINGTON Folk-speech S. Cheshire, ‘A thing for the once’ an unusual or unprecedented thing.
1924 A. D. SEDGWICK Little French Girl I. viii. 74 ‘He came twice afterwards.’.. ‘I didn't know that. I thought it was only the once.’
1990 R. DOYLE Snapper (1993) 146 Maybe I will if you're goin' to get into fights all the time.{em}No, Sharon, Jimmy Sr assured her.{em}It was just the once.
Dear Anthony,

I just started reading your book on C++ Concurrency: I really enjoyed the 1st chapter. I've spotted a few completely trivial typos, that the copy-editor might also catch before the book goes to print. Just in case he/she doesn't, I am pointing them out below. I may have more of these in the weeks to come.

Alexandros Gezerlis


p. 6 "a computer with precisely two task to do" --> "a computer with precisely two tasks to do"

p. 7 "can be used whether you're application" --> "can be used whether your application"

p.16 "However, this performance cost does not necessarily imply a higher abstraction penalty though" --> "However, this performance cost does not necessarily imply a higher abstraction penalty" or "This performance cost does not necessarily imply a higher abstraction penalty though".

p. 18 "as chip manufacturers choose add more processing power" --> "as chip manufacturers add more processing power" or "as chip manufacturers choose to add more processing power".

p. 18 "quite how simple to use the classes and functions from the C++ Standard Library can be" --> "quite how simple using the classes and functions from the C++ Standard Library can be"