High Performance Python

Errata for High Performance Python

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. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

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



Version Location Description Submitted By Date Submitted Date Corrected
Safari Books Online
?
Last paragraph of section 1.2 Putting the Fundamental Elements Together

The second sentence of the last paragraph of section 1.2 Putting the Fundamental Elements Together says, "For example, let's assume we change the code to use multiple CPU cores such that each core gets a chunk of the numbers from 1 to sqrtN." This should be from 2 to sqrtN as it is in the code above it, not 1. For the example problem, starting at 1 as a factor of a prime number will always yield incorrect results.

Note from the Author or Editor:
Changed the starting value from 1 to 2

Mike Mabey  Jul 01, 2014 
PDF
Page 3
first full para

"drastically effect computing" --> "drastically affect computing"

Note from the Author or Editor:
s/effect/affect

dml  Jun 13, 2014 
PDF
Page 3
3rd para from bottom

"are computer out" --> "are computed out"

Note from the Author or Editor:
s/computer/computed

dml  Jun 13, 2014 
PDF
Page 6
figure 1-2

The font size on the figure axes is much too small to read easily. In general, the figure is overly busy. I would get rid of the grey background, get rid of the figure title (the caption does just fine), and reduce the number of horizontal grid lines. I would also change the axis label "read_latency" to remove the underscore. On the subplots for read latency and size, maybe label every other decade (to reduce the number of labels on the y-axis).

Note from the Author or Editor:
Fonts increased and figure made a bit more simple

dml  Jun 13, 2014 
PDF
Page 7
2nd para under "Communications Layers"

"busse" --> "buses"

Note from the Author or Editor:
s/busse/buses

dml  Jun 13, 2014 
PDF
Page 7
4th para under "Communications Layers"

"transfered" --> "transferred"

Note from the Author or Editor:
s/transfered/transferred

dml  Jun 13, 2014 
PDF
Page 7
5th para under "Communications Layers"

"than were mentioned before while" --> "than were mentioned before. While"

Note from the Author or Editor:
This paragraph was restructured since this errata was submitted.

dml  Jun 13, 2014 
PDF
Page 10
last para

"without having the transfer" --> "without having to transfer"

Note from the Author or Editor:
s/the/to

dml  Jun 14, 2014 
PDF
Page 10
last para

"benifits" --> "benefits"

Note from the Author or Editor:
s/benifits/benefits

dml  Jun 14, 2014 
PDF
Page 12
last line

"pervalent" --> "prevalent"

Note from the Author or Editor:
fixed.

dml  Jun 14, 2014 
PDF
Page 13
2nd to last para

"flakey" --> "flaky"

dml  Jun 14, 2014  Aug 21, 2014
PDF
Page 16
2nd to last para

"coordinatess" --> "coordinates"

dml  Jun 14, 2014  Aug 21, 2014
PDF
Page 17-18

Choose one and stick with it: "co-ordinate" or "coordinate".

Note from the Author or Editor:
Changed in favor of coordinates.

dml  Jun 14, 2014 
PDF
Page 19
first para

"reasonble" --> "reasonable" "when the profile" --> "when we profile"

dml  Jun 14, 2014  Aug 21, 2014
PDF
Page 24
last para before subsection on "Simple timing"

"interferring" --> "interfering"

dml  Jun 15, 2014  Aug 21, 2014
PDF
Page 25
second bullet

"kernal" --> "kernel"

dml  Jun 15, 2014  Aug 21, 2014
PDF
Page 31
4th para under "runsnake"

"exectuion" --> "execution"

dml  Jun 16, 2014  Aug 21, 2014
PDF
Page 36
first para under "memory_profiler"

"It operates in a very similar way, it must be noted that the current implementation is not as efficient as line_profiler and takes a lot longer to run." This seems unfair to memory_profiler. It seems to be doing something quite different from line_profiler, so it's hard to understand how one can compare their "efficiency". That is, if line_profiler is more efficient than memory_profiler, why not use line_profiler? Well, because it's doing something else, and doesn't give the types of results that memory_profiler gives. So in what sense is that "more efficient"? It might be better-- nicer, and conveying just as much information-- simply to state that memory_profiler takes longer to run, and leave it at that.

Note from the Author or Editor:
Already fixed

dml  Jun 16, 2014 
PDF
Page 37
3rd to last para

"On the next line we see that the process grew by approximately a further 48MB inside the loop, this will be accounted for by all the unique floating point numbers that are generated inside the complex z updates in the innermost loop." I have two questions about this statement. First of all, "On the next line" seems to refer to line 13, since the para above is talking about line 12. Line 13 of the output shows about 33MB, not 48MB, being allocated. I don't see 48MB anywhere in the listing. So perhaps the "48" is from an earlier draft? It isn't clear. Second of all, how do you know that that 33MB allocation on line 13 is due to the "unique floating point numbers generated inside the complex z updates"? After all, line 13, is this bit of code: for i in range(len(zs)): That makes it seem like the 33MB is due to allocating range(len(zs)), which presumably is a big static list that gets created all at once. By contrast, the complex z updates happen in line 18 of the listing: z=z*z+c This line (18) has 0MB incrementally associated with it. So can you please clarify: (1) what 48MB are you referring to; and (2) how can you attribute it to the z updates, rather than to the range(len(zs))?

Note from the Author or Editor:
Already fixed

dml  Jun 16, 2014 
PDF
Page 37
2nd para from bottom

"RAM allocation in this function is fairly low." That sounds absurd. According to the listing, this function requires 32MB of RAM just to iterate over an array. In what world is that considered a small amount of memory? Maybe you're comparing to lots of other Python code, but to somebody coming from a C or Fortran background, this looks pretty bloated.

Note from the Author or Editor:
Already fixed

dml  Jun 16, 2014 
PDF
Page 41
last para of text

"Note the call to hpy.setrelheap() ..." The code listing contains no call to hpy.setrelheap().

Note from the Author or Editor:
Fixed in Rachel Head's PDF

dml  Jun 18, 2014 
PDF
Page 44
last para

"we can keep the console open using the sleep," I assume by "the sleep" you mean "the call to time.sleep".

Note from the Author or Editor:
Edit marked in PDF for Rachel Head

dml  Jun 18, 2014 
PDF
Page 51
bullet list under "Strategies to profile your code"

Bullet points mix present and past tense. Suggest consistency. Bullets 1, 2, 5, 6 use present tense: disable, disable, run reboot. Bullets 3, 4 use past tense: used, disabled.

Note from the Author or Editor:
Fixed in Rachel Head's PDF

dml  Jun 21, 2014 
ePub
Page 59.0/330
timefn example

In the example of timefn, there should be a new version of calc_pure_python that uses the decorated version of calculate_z_serial_purepython. In its absence (i.e. if you use calc_pure_python as is) you get two timings, the timing based on the decorator, then the timing around it based on calc_pure_python time.time() calls.

Note from the Author or Editor:
Already fixed

Louis Luangkesorn  Jun 09, 2014 
PDF
Page 60
Last para, and first para on p.61

Note this comment refers to early release v4. My earlier comments refer to early release v3. The description of the "buckets" in a list/array goes back and forth between describing the buckets as holding the data, and as holding pointers to the data. Specifically, this sentence states that the buckets store the data: "In order to look up any specific element in our list, we simply need to know which element we want and remember which bucket our data started in." The next sentence states that the buckets actually store a pointer to the data: "Since all of the data will occupy the same amount of space (one ďbucketĒ or, more specifically, one integer sized pointer to the actual data), we donít need to know anything about the type of data that is being stored to do this calculation." (By the way, that should be "integer-sized".) The next two sentences revert to describing the buckets as storing the data: "If, for example, we needed to retrieve the first element in our array, we simply go to the first bucket in our sequence, M, and read out the value inside it. If, on the other hand, we needed the 5th element in our array, we simply need to go to the M+5 Ďth bucket and read its content." I suppose you're trying to avoid being pedantic, but it should be pretty easy to make clear that consecutive buckets store pointers to the actual data, and stick with that description throughout.

Note from the Author or Editor:
Added a note making sure the reader understands that a block is in fact a pointer to data.

dml  Jun 23, 2014 
PDF
Page 61
Para just under Example 3-2

"In order to know that the element we are searching isnít in the array, we must first check it with every other element and we will reach the final return -1 statement. In fact, this algorithm is exactly the algorithm that list.index()." --> "In order to know that the element we are searching FOR isnít in the array, we must first check EVERY ELEMENT IN THE ARRAY BEFORE REACHING the final return -1 statement. In fact, this algorithm is exactly the algorithm that list.index() USES."

Note from the Author or Editor:
Changed to: In order to know that the element we are searching for isnít in the array, we must first check it against every other element. Eventually, we will reach the final return -1 statement. In fact, this algorithm is exactly the algorithm that list.index() uses.

dml  Jun 23, 2014 
PDF
Page 62
2nd para under "More efficient search"

"The two elements necessary are the sorting algorithm and then the searching algorithm." Since the word "elements" is used repeatedly in the surrounding text with its technical meaning of "a single entry in a list or array", consider changing "elements" here to some other word, e.g., "pieces" or "ingredients" or "routines"-- anything like that.

Note from the Author or Editor:
Changed elements to ingredients.

dml  Jun 24, 2014 
PDF
Page 62
3rd para under "More efficient search"

"Once a list has been sorted, we can use a binary search algorithm (Example 3-3) to find our desired element, which has an average case complexity of O(logn). It achieves this by first looking at the middle of the list and comparing this value with the desired value. If this midpointís value is less than our desired value, then we consider the left half of the list and continue halving the list like this until the value is found." The algorithm in Example 3-3 looks at the middle, and "If this midpoint's value is less than our desired value, then we consider the RIGHT half of the list." As long as I'm on this paragraph, note that the first sentence interposes "our desired element" into the phrase "binary search algorithm, which has an average complexity..." Better would be something like "... we can find our desired element using binary search, which has ..." Also, note that the algorithm continues "halving the list like this until the value is found, or until the value is known not to occur in the sorted list."

Note from the Author or Editor:
Marked in the PDF to Rachel

dml  Jun 24, 2014 
PDF
Page 62
Last para before "More efficient search"

"itís" --> "its"

dml  Jun 23, 2014  Aug 21, 2014
PDF
Page 62
Last para before "More efficient search"

"... by disregarding any intrinsic ordering to the data and instead ascribing another, more peculiar, organization." This all sounds very odd. First of all, data structures don't really "ascribe" an ordering, they impose an ordering. "Ascribe" is pretty passive-- it just says that the data structure identifies the cause of some ordering that's already out there somehow. Second, "peculiar" is a strange word to use. Why is a dictionary's ordering any more strange ("peculiar") than whatever other order might be imposed? I think you mean "specific" or "particular" or something down that line. Finally (and this is a minor quibble), a lot of data don't have an "intrinsic" ordering. For example, if the dictionary maps words harvested from a text to the count of times each word appears, there isn't any particular "intrinsic" order to the words (or rather, one could identify several different "intrinsic" orderings, depending on the application).

Note from the Author or Editor:
Changed ascribe to specify and "any intrinsic ordering to" to "the original ordering of"

dml  Jun 23, 2014 
PDF
Page 63
Example 3-4

"# bisect.bisect_left will return the first value in the haystack that is greater # than or equal to the needle" Looking at the code that follows, bisect.bisect_left actually returns the index to that value, rather than the value itself.

Note from the Author or Editor:
marked in PDF to rachel

dml  Jun 24, 2014 
PDF
Page 64
first list item under "Lists vs Tuples"

"Lists are a type of array called ďdynamic arraysĒ and as a result are mutable and allow for resizing the number of elements that can be held" This is a bit of a quibble, but "as a result" implies causality in the wrong direction. Lists are mutable and allow for resizing. As a result they are called "dynamic arrays". Also, why not a period at the end of this sentence? Similar comments apply to the next list item, which claims that calling tuples "static arrays" makes them immutable.

Note from the Author or Editor:
This area was generally restructured for better clarity.

dml  Jun 24, 2014 
PDF
Page 65
2nd to last para of chapter

"abstract code will be much slower than code specifically designed to solve a particular problem." You probably mean "general code" rather than "abstract code"-- "abstract" is not the opposite of "particular". I would especially avoid "abstract" since the term has a loaded meaning in some object-oriented languages (where an abstract method gives a pattern, but not an implementation).

Note from the Author or Editor:
Changed 'abstract' to 'general'

dml  Jun 24, 2014 
PDF
Page 65
2nd to last para of chapter

"These overheads can be removed if we also force all the data in our list to be of the same type." This sentence doesn't need the "also", since it just makes explicit the advice offered by the sentence before. In addition, it's not clear why this sentence mentions only lists, when the sentence before seems to be talking about tuples as well. Maybe there is some deeper idea here that you're trying to put across?

Note from the Author or Editor:
Changed sentence to: These overheads can be removed if we force all of our data to be of the same type, which would allow us to use the `array` module, a `numpy.ndarray` or several other such objects.

dml  Jun 24, 2014 
PDF
Page 66
2nd para under "Lists as dynamic arrays"

"itís" --> "its"

dml  Jun 24, 2014  Aug 21, 2014
PDF
Page 67
Example 3-5

"List overallocation equation in py2.7" This is probably a list allocation, rather than overallocation equation. M appears to be the number of items allocated; overallocation would be M-N. Speaking of which, while the graph looks kind of cool because of the funnel, it's probably more instructive just to see the stair-step function of how much memory gets allocated. You could add the 45-degree "exact allocation" line if you worry that people won't understand that zero over-allocation is possible for lists of certain sizes. I complained about the figures earlier, but I'll do it again as long as I'm here. The font size on the axes labels and tick labels is far too small. The figure doesn't need a title when it already has a caption. There's no need to add a grey background. The lines could be in a much higher-density color than the sort of pale, washed-out blue it currently uses.

Note from the Author or Editor:
Reference to equation updated. Figured made more readable. I also kept the figure contents the same since the overall allocation version of the figure seemed overly complicated (and it's just a 45 degree rotation of the figure that is already there!).

dml  Jun 24, 2014 
PDF
Page 68
2nd para

"This sequence of events is shown visually in Figure Figure 3-3 below." Literally says "Figure Figure". First one is plain text, second one is part of the link.

Note from the Author or Editor:
removed extra 'figure'

dml  Jun 25, 2014 
PDF
Page 70
first para

"more information about itís current state" --> "more information about its current state"

dml  Jun 25, 2014  Aug 21, 2014
PDF
Page 70
2nd para

"is something python does in the background" "Python" should be capitalized.

dml  Jun 25, 2014  Aug 21, 2014
PDF
Page 70
2nd para

"when a variable isnít used anymore python frees the use of the memory back to the operating system" --> "... frees the memory back..." or "... releases the memory back..." Also, "Python" should be capitalized.

Note from the Author or Editor:
Sentence generally restructured to: ... when a variable isnít used anymore Python frees the memory used by that variable, giving it back to the operating system for use in other applications (or for other variables).

dml  Jun 25, 2014 
PDF
Page 70
All of chapter 3

With all the space this chapter devotes to describing the problem with appending items to lists, I was surprised not to see anything about pre-allocating a list. Many dynamic languages have a mechanism to declare an empty structure with a given size, in order to allocate sufficient memory up-front. Does Python not have such a feature? Or are you planning to talk about it later? (Or did I just miss it somehow?) If you do talk about it later, maybe give a forward pointer to the fact that you'll do so.

Note from the Author or Editor:
In the chapter describing matrix computations (particularly the section on python lists), we address this issue in detail. I added a reference to it in the wrap-up section of the lists/tuple chapter.

dml  Jun 25, 2014 
PDF
Page 71
first para

"...sets do not actually contain data, they are simply a collection of unique keys." If you're using a set to store keys, then the keys are almost certainly the data that interest you. Maybe a better word than "data" is "values" since this sentence is meant to contrast the keys in sets with the key-value pairs in dictionaries.

Note from the Author or Editor:
Changed to: ... sets do not actually contain values ...

dml  Jun 27, 2014 
PDF
Page 71
last para

"before we were restricted to, at best, O(log n) lookup time on lists/tuples with no intrinsic order" I don't think "no intrinsic order" is correct here. You clearly mean to indicate that the user doesn't know the index of the item of interest, so the item can't be accessed in O(1) time. However, not knowing the index does not mean that the items have "no intrinsic order". To get that O(log n) behavior requires the items to be sorted, which implies there is some meaningful way to order the data. If the items truly have no intrinsic order, then search is O(n).

Note from the Author or Editor:
Change O(log n) to O(n)

dml  Jun 27, 2014 
PDF
Page 72
Footnote 1

"guarentee" --> "guarantee" Also, that sentence needs a period.

dml  Jun 27, 2014  Aug 21, 2014
PDF
Page 74
Section "How do dictionaries and sets work?"

This entire section assumes the reader knows what hashing means. But you never come out and define it, exactly. Instead, there are two sentences that hint around about it: "This efficiency is a result of a very clever usage of hash functions [Link to Come] in order to create list-like indexes for data. By turning the dataís key into something that can be used like a list index..." If you don't already know what a hash function and a hash table are, that first sentence can create the impression that a hash function is something that is used in a clever way to create indices. That's needlessly indirect-- the hash function itself creates the indices. It's not some function, designed for another purpose, that is somehow cleverly bootstrapped into creating indices. Another thing I find vague about that first sentence is the phrase "list-like indexes." I know you mean "an index like the kind used for lists" but that is NOT what "list-like indexes" means. "List-like index" means an index that is somehow like a list. But indices are not like lists. They are like integers. In fact, they ARE integers. So just call them integers. After that, if you really want to remind the reader that integers are also used to index lists, go ahead and do it. The second sentence is also vague. Why is the data's key "turned into something that can be used like a list index", as opposed to being turned into an integer index? Again, a direct description would be better. And again, a "list index" is an odd phrase, because it implies that there are multiple types of indices, one of which is called a "list index". Might be better to say "an index into a list." That (intended) link to a section on hash functions compounds the vagueness. For readers who don't know what a hash function is, that link will make them think that you aren't actually defining hash functions here, and that they need to click forward in order to learn about them. It may create the impression that these two sentences aren't really about hash functions, after all, but about the way hash functions are used. So I would encourage you to be direct-- make plain that you're actually defining hash functions (and, by extension, hash tables) here. And then use direct, straightforward descriptions, rather than just describing properties of hash functions. In short, you need to bite the bullet and just define the hash function in a straightforward way. Then describe how the hash function is used to construct the table.

Note from the Author or Editor:
Changed the sentence at hand to: This efficiency is the result of a very clever usage of hash functions to turn an arbitrary key (ie: a string or object) into an index for a list. The hash function and list can later be used to know where any particular piece of data is right away without a search.

dml  Jun 27, 2014 
PDF
Page 74
Explication of code point #4

"This is because sets guarantee uniqueness over the keys it contains." There is a count agreement between "sets" and "it".

Note from the Author or Editor:
Restructured callout to: ... sets guarantee the uniqueness of the keys they contain, if you try to add an item that is already in the set, that item simply wonít be added.

dml  Jun 27, 2014 
PDF
Page 74
First regular para

"Thus, the complete algorithms performs" --> "Thus, the complete algorithm performs" Also, consider "complete" --> "overall"

Note from the Author or Editor:
only first correction applied

dml  Jun 27, 2014  Aug 21, 2014
PDF
Page 74
First para under "How do dictionaries and sets work?"

"Dictionaries and sets use a hash table in order to achieve its" --> "Dictionaries and sets use a hash table in order to achieve their"

dml  Jun 27, 2014  Aug 21, 2014
PDF
Page 75
first full para

"(ie: for a dictionary" --> "(i.e., for a dictionary"

dml  Jun 28, 2014  Aug 21, 2014
PDF
Page 75
first full para

"if two itemís hash" This means "if the hash of two item". Minimal fix is "if two items' hash" (move the apostrophe). Then it means "if the hash of two items" which is getting closer to correct. I might go a step further and say "If two items' hashes" since both items have a hash, not a single hash between them. But that sounds a bit clunky. So I might go even further and change the whole sentence to something more like "This means that if hashing two items gives the same last 3 binary digits..."

Note from the Author or Editor:
Fixed to "This means that if hashing two items gives the same last 3 binary digits..." for extra clarity.

dml  Jun 28, 2014 
PDF
Page 75
footnote 2

Footnote is missing a period on the final sentence.

dml  Jun 28, 2014  Aug 21, 2014
PDF
Page 75
Second para under "Inserting and Retrieving"

"So, if we have allocated 8 blocks of memory and our hash value is 28975, we consider the bucket at index 28975 & 0b111 = 7. If, however, our dictionary has grown to have 256 items then the mask becomes 0b11111111." Question-- First sentence says that the mask is based on the number of blocks allocated, while the second sentence implies the mask depends on the number of items stored in the dictionary. If both sentences are correct, it implies the dictionary only allocates memory as needed, i.e., it never over-allocates memory in the fashion of lists. This seems unlikely (especially because hash tables often start with a significant amount of memory allocated, in order to allow the hash function to do a good job spreading the indices out, to avoiding hitting the same indices over and over). So the question is, do Python dictionaries only allocate just enough memory for the items stored, or is the second sentence wrong?

Note from the Author or Editor:
Changed text to: If, however, our dictionary has grown to contain 512 blocks of memory

dml  Jun 28, 2014 
PDF
Page 76
reference to footnote 3

"...the value 5 is unimportant 3." "Unimportant" makes it sound like it's an arbitrary number, but the footnote seems to say it isn't arbitrary. So maybe you mean the value 5 is unimportant to the current discussion. Also, there's a space between the "unimportant" and the footnote reference "3". Also, your previous footnote put the reference after the period, whereas this one is before the period. But this kind of detail clearly isn't important to the authors of this text, because there are so many inconsistencies in the formatting that I haven't bother pointing them out. Just look at the completely random capitalization style on subheadings for a good example. At least one place where this footnote is consistent with the last one, is the failure to put a period at the end of the footnote itself.

Note from the Author or Editor:
Good point about the use of "unimportant". Changed to "unimportant to the current discussion". Formatting fixed for the reference and general consistency of capitalization.

dml  Jun 28, 2014 
PDF
Page 79
first para under "resizing"

"(ie: more" --> "(i.e., more" I don't plan to report this error anymore.

dml  Jun 28, 2014  Aug 21, 2014
PDF
Page 79
last para of "Resizing"

Here's a good example of the lack of consistency I mentioned a few pages ago. This paragraph uses two typographic styles to convey stress-- first, the all-caps "OR", and second, the boldfaced "only happens during an insert". I know it's not a big deal, and I know this is an "early release", and I know this book has two authors. All of that can explain how styles aren't kept consistent throughout the text. But in a single paragraph? Come on. This lack of attention to details just comes across as lazy.

Note from the Author or Editor:
Changed all stresses to use italics.

dml  Jun 28, 2014 
PDF
Page 79
2nd para under "Hash functions and Entropy"

"returns the objects placement in memory" --> "returns the object's placement in memory" (Add apostrophe)

dml  Jun 28, 2014  Aug 21, 2014
PDF
Page 80
3rd full para

"The hash function can be arbitrary as long as it constantly gives the same result for the same object." Probably "constantly" should be "consistently".

Note from the Author or Editor:
s/constantly/consistently

dml  Jun 28, 2014 
PDF
Page 81
2nd para before Example 4-6

"For example, for a dictionary with 4 elements, the mask we use is 0b111." Again there's this ambiguity about how the mask gets chosen-- based on the number of elements in the dictionary, or based on the amount of memory allocated to the dictionary. From section "Resizing" on p79, it seems like the mask is changed only when the allocated memory is changed. That matches my intuition about how hashes work. But the sentence quoted above implies that the mask depends on the number of elements in the dictionary. Please clarify.

Note from the Author or Editor:
A note has been added describing how to find the mask given the current length of the dictionary.

dml  Jun 28, 2014 
PDF
Page 85
last para before Example 4-10

"...simply by making the sin function local a tight loop which calls it." This isn't grammatical. Probably you mean "local to a tight loop", but you may have some other expression in mind.

dml  Jun 28, 2014  Aug 21, 2014
PDF
Page 85
first para under "Wrap Up"

"can greatly effect the resulting performance" --> "can greatly affect the resulting performance"

dml  Jun 28, 2014  Aug 21, 2014
PDF
Page 85
first para under "Wrap Up"

"are a very intrinsic part" --> "are an intrinsic part" "Intrinsic" doesn't really admit degrees. Either dictionaries are intrinsic part of Python's internal functionality, or they aren't.

dml  Jun 28, 2014  Aug 21, 2014
PDF
Page 85
last para

"In the next chapter, we will explore generators which allows us to provide data to code in any dynamic order we want and without necessarily storing it in memory beforehand." This sentence is a bit unclear. Here are the things I know to be wrong, just from the rules of English: -- "generators which" --> "generators, which" -- "generators, which allows" --> "generators, which allow" There are two other bits I have trouble with (since I don't know generators well enough): -- "provide data to code" I think this means you can provide data to the program, but since "generator" could be a Lisp-like ability to define high-level macros, it could also mean that there is some way to convert data into code. -- "storing it" The "it" is a weak reference. I assume "it" refers to "data", meaning you don't have to store the data in memory beforehand. But I'm not sure, since so much has happened, in terms of language, between "data" and "it".

dml  Jun 28, 2014 
PDF
Page 85
last para

"This letís us side-step" --> "This lets us side-step"

dml  Jun 28, 2014  Aug 21, 2014
PDF
Page 88
Definition of xrange

There is a comment marker (#) on this line of the definition: yield start #(1) In other code snippets with the numbered bullets like (1), there have not been comment markers.

Note from the Author or Editor:
Normalized all examples to have comment markers before callout numbers.

dml  Jun 29, 2014 
PDF
Page 88
First full para

"So, if the range is from 1 to 10,000, the function will do 10,000 appends to the numbers list... As a result, ... the range version of the loop above uses 10x more memory..." This reads oddly because, near the top of the paragraph, the example runs "range" from 1 to 10000, while the end of the paragraph says there's a factor of 10 difference. That factor of 10 refers to the code, which runs "range" from 1 to 10. Suggest you make the example in the text match the sample code (or vice-versa). I.e., make the code say "for i in range(1, 10000)", or else make the example in the paragraph say "So, if the range is from 1 to 10, ..."

Note from the Author or Editor:
Change the example to range from 1 to 10000.

dml  Jun 29, 2014 
PDF
Page 93
last para

"if the max is 3 sigma larger than the mean" --> "if the max is more than 3 sigma larger than the mean"

Note from the Author or Editor:
Made suggested change.

dml  Jun 30, 2014 
PDF
Page 93
last para

"... a function that returns a value that evaluates to True for data that should be kept and a value that evaluates to False if a value should be disregarded." Probably that last "value" should be data, in order to keep the second part of the sentence parallel with the first. Thus, "... to False for data that should be disregarded." Probably "disregarded" should be "discarded" (more nearly opposite of "kept"). In the phrase "a value that evaluates to True", I usually think of "value" as the final answer after evaluation. So I would expect to read either: (1) "... a function that returns True for data...; or (2) "... a function that returns an expression that evaluates to True..."

Note from the Author or Editor:
Changed sentence to: a function that returns True for data that should be kept and False for data that should be discarded.

dml  Jun 30, 2014 
PDF
Page 95
Note 1 to Example 5-5

"any elements which do not satisfy" --> "any elements that do not satisfy"

dml  Jun 30, 2014  Aug 21, 2014
PDF
Page 95
first full para

"are performed which can drastically reduce" --> "are performed, which can drastically reduce" (add comma)

dml  Jun 30, 2014  Aug 21, 2014
PDF
Page 95
2nd to last para

"by opening the file multiple time" --> "by opening the file multiple times"

dml  Jun 30, 2014  Aug 21, 2014
PDF
Page 95
2nd to last para

"This can be changed by opening the file multiple time and using this to point to the parts of the data we like" It isn't clear to what the second "this" refers. In other words _what_ gets used to point to parts of the data?

Note from the Author or Editor:
Changed sentence to: This can be changed by opening the file multiple times and using the various file descriptors to point to the exact data we like (or use te linecache module), ...

dml  Jun 30, 2014 
PDF
Page 96
first para under "Wrap Up"

"By formulating our anomaly finding algorithm as iterators" --> "By formulating our anomaly finding algorithm with iterators"

Note from the Author or Editor:
s/as/with

dml  Jun 30, 2014 
PDF
Page 97
first para

"operate on number and" --> "operate on numbers and" Also, consider adding a comma after "numbers", in order to better separate "the only thing the computer knows" from the reader's "knowing how to do multiple of those calculations".

Note from the Author or Editor:
Updated to, ... the only thing the computer knows how to do is operate on numbers, and knowing how to do several of those calculations at once will speed up your program.

dml  Jul 02, 2014 
PDF
Page 97
2nd para

"effects the CPU" --> "affects the CPU"

dml  Jul 02, 2014  Aug 21, 2014
PDF
Page 98
2nd para of bird icon under "Intro to the Problem"

"et al.." --> "et al." (remove extra period)

dml  Jul 02, 2014  Aug 21, 2014
PDF
Page 98
bird icon para

"transfered" --> "transferred" I flagged this once before, so do a global search-- I don't plan to flag it again.

Note from the Author or Editor:
Fixed in editing.

dml  Jul 02, 2014 
PDF
Page 99
bird icon para

"how a couple drops of dye diffuses" --> "how a couple of drops of dye diffuse" (add "of", drop the "s" from "diffuses")

dml  Jul 02, 2014  Aug 21, 2014
PDF
Page 99
bird icon para

"So, instead of solving for how a couple drops of dye diffuses through water, we would be solving for how the heat from several drops of hot water diffuses through cold water." Not the best example for heat diffusion. If you put drops of hot water into cold water, the physical diffusion of water molecules is going to dominate the conduction of heat by water. A better example would be a solid. Why not a computer analogy-- like this: "So, instead of solving for how a couple of drops of dye diffuse through water, we might be solving for how the heat generated by a CPU diffuses into a heat sink."

Note from the Author or Editor:
Changed text as per suggestion.

dml  Jul 02, 2014 
PDF
Page 99
para before Euler's discretization

"approximate it to discrete volumes" --> "approximate it using discrete volumes" OR "approximate it as discrete volumes" ("using" is probably better)

dml  Jul 02, 2014  Aug 21, 2014
PDF
Page 99
para before Euler's discretization

"takeís the derivative" --> "takes the derivative" Even better is to eliminate the phrase altogether: "Eulerís method simply writes the derivative as a difference"

Note from the Author or Editor:
Changed to: Eulerís method simply takes the derivative

dml  Jul 02, 2014 
PDF
Page 99
para after Euler's discretization

"In fact, as dt approaches zero, Eulerís approx‐ imation becomes exact." This is only true in infinite-precison arithmetic. Since this book is explicitly about computer approximations, using a language that employs finite-precision arithmetic, this statement is not true. In finite-precision arithmetic, as dt approaches zero, truncation errors of another kind start to increase the error made by each step.

Note from the Author or Editor:
While that is not a subject for this book, I will add a note stating that setting dt arbitrarily close to 0 only works theoretically and that there are limitations for doing this on the computer.

dml  Jul 02, 2014 
PDF
Page 99
para after Euler's discretization

"Cauchey Problem" --> "Cauchy problem" (get rid of the "e", and no need to capitalize the "P").

dml  Jul 02, 2014  Aug 21, 2014
PDF
Page 100
2nd para under spatial discretization

"spacial" --> "spatial"

dml  Jul 03, 2014  Aug 21, 2014
PDF
Page 100
2nd para under spatial discretization

The description of the "matrix" boundary conditions is a little loose. For example, the discretization you're talking about describes a vector, not a matrix, of values. If it was a matrix, you couldn't just talk about "index N-1" and so forth. I realize the reason for this is that you are keeping in mind that normally one discretizes 2D or 3D space, rather than a line. But you might want to think about making the description more internally-consistent. Another thing I'm not crazy about is the reference to "index N+1". For the N-dimensional vector you're describing, index N is the first element outside the bounds of the problem, and that index "wraps" to index 0. Since the discretization doesn't invoke more than one cell beyond that where the derivative is being approximated, there's no need to bring in a fictitious cell N+1 that the algorithm will never try to access.

Note from the Author or Editor:
Made specific reference to a particular dimension in the matrix for the boundary condition. In addition, changed the N+1 example to simply N.

dml  Jul 03, 2014 
PDF
Page 100
Example 6-1 and the para preceding it

Description of Example 6-1 calls it "pseudo code". The caption for Example 6-1 calls it "pseudocode". Pick one spelling and stick with it. Also, in the caption, the "pseudo" is missing the "e". As long as we're on the subject of consistency, the caption to Example 6-1 uses title-style initial capitals, but the other Example captions I checked use regular sentence-style capitalization.

Note from the Author or Editor:
Fixed for consistency (sentence capitalization and 'pseudocode')

dml  Jul 03, 2014 
PDF
Page 100
Example 6-1

"D = 1" Not sure why you define D when the code never uses it.

Note from the Author or Editor:
add D factor to second term in unew update.

dml  Jul 03, 2014 
PDF
Page 100
Example 6-1

"Example 6-1. Psudocode for Matrix Initialization for 1D Diffusion" Caption is not correct. Example 6-1 implements 1D diffusion. It does not merely initialize the matrix.

Note from the Author or Editor:
Changed caption to: Pseudocode for 1D diffusion

dml  Jul 04, 2014 
PDF
Page 104
Example 6-3

Function evolve() takes {grid} as an argument, uses it to calculate {new_grid}, then returns {grid}. It ought to return {new_grid}.

Note from the Author or Editor:
Changed: return grid to return new_grid

dml  Jul 05, 2014 
PDF
Page 104
Example 6-3

This line of code new_grid = [[0.0 for x in xrange(ymax)] for x in xrange(xmax)] works OK. However, it might be easier to read/understand if the variable in the "inner" comprehension was y rather than x: new_grid = [[0.0 for y in xrange(ymax)] for x in xrange(xmax)]

Note from the Author or Editor:
Changed new_grid = ... to: new_grid = [[0.0,]*ymax for x in xrange(xmax)]

dml  Jul 05, 2014 
PDF
Page 104
para above Example 6-4

"how big of a region we be simulating" --> "how big of a region we will be simulating" Even better: "how big of a region we will simulate"

Note from the Author or Editor:
Changed to "how big of a region we will simulate"

dml  Jul 05, 2014 
PDF
Page 104
Example 6-3

It might be nice to remind us somewhere that kernprof.py requires the @profile decorator on function evolve().

Note from the Author or Editor:
Added note after example 6-5 about decorating functions with @profile.

dml  Jul 06, 2014 
PDF
Page 105
Example 6-5

I have a few questions/comments about the profiling results. Probably not all worth going into in the text. What value of {num_iterations} was used here? I assume 10, since that's how many times the extents are pulled out of {grid_shape}, and the number of returns. It's odd how long each execution of xmax, ymax = grid_shape takes. Why does that take 3.9 seconds per hit, when a line like grid_xx = grid[(i+1)%xmax][j] ... takes only 1.6 seconds? One would think that extracting values from a 2-tuple would be negligibly fast. The line for i in xrange(xmax): gets 5130 hits, as opposed to 10 (the number of hits for other statements at the same "level" of the code). I assume this means xrange() gets called 513 times, in order to fill in the total range? Since the total range is 1024, does that mean xrange() only generates about two elements at once?

Note from the Author or Editor:
You can see that the function gets called 10 times by how many times "return grid" is called. Moreover, the grid size is (512, 512) which is why "for i in xrange(xmax)" is called 513 * 10 times. 512 for each element in the range and then once more for the termination condition. Lastly, the "xmax, ymax = grid_shape" is slow because it must find 'grid_shape' from the global namespace which can be quite time consuming! Callouts into the example have been added for clarity and to give the reader a way of better understanding line_profiler output.

dml  Jul 06, 2014 
PDF
Page 105
1st para under "Problems with allocating too much"

"any time spent not solving the CPU bound problem is low hanging fruit for optimization" I don't think you mean "low hanging fruit." Low-hanging fruit is the fruit closest to the ground, and therefore the easiest to pick. So low-hanging fruit for optimization is things that are quite easy to optimize. For example, replacing range() with xrange(). By contrast, time not spent solving the CPU-bound problem is not necessarily easy to eliminate. It might be setup time that is required. It might be formatting output to a file or screen, which is conceptually straightforward, but often hard to optimize without juggling memory and threads. Furthermore, in the context of this paragraph, "low-hanging fruit" doesn't make much sense. The point of this paragraph is that, for the given problem, not much time is actually spent doing things outside the CPU-bound problem. So even if optimizing those parts does happen to be easy (i.e., even if it *is* low-hanging fruit), there may not be much point.

Note from the Author or Editor:
Changed "low hanging fruits" to "an obvious place"

dml  Jul 06, 2014 
PDF
Page 106
function loop_fast()

The loop shown in loop_fast() would benefit from even more aggressive removal of work from the loop. The loop finds the sum of a bunch of terms times a constant factor: result = sum_{i=0}^{num_iterations-1} i*factor This can be rewritten as result = factor * sum_{i=0}^{num_iterations-1} i In other words, hoist the entire multiplication out of the loop. Then you just have something like factor * sum(xrange(num_iterations)) Of course, the sum itself has an easy arithmetic reduction, so if you pursue this too far you ruin the point of the example.

Note from the Author or Editor:
While I completely agree, this was meant to be a trivial example. Further optimizing the code removes takes away the point. Using the arithmetic series it could always just be written as, return sin(num_iterations) * num_iterations * (num_iterations + 1) / 2.0

dml  Jul 06, 2014 
PDF
Page 109
last para

"do things to disincentives" --> "do things to disincentivize" Can't edit my earlier submission on this, but I was wrong there. "Incentive" is a noun or adjective. This sentence uses it as a verb. Therefore "incentivize". Since this is kind of clunky, even better might be ""do things to dissuade" or "do things to discourage"

dml  Jul 07, 2014  Aug 21, 2014
PDF
Page 109
last para

"do things to disincentives" --> "do things to disincentive"

dml  Jul 07, 2014  Aug 21, 2014
PDF
Page 110
2nd para

"does not generally effect" --> "does not generally affect"

dml  Jul 07, 2014  Aug 21, 2014
PDF
Page 110
last para

"stalled- cycles-fontend" --> "stalled- cycles-frontend" (missing "r")

dml  Jul 07, 2014  Aug 21, 2014
PDF
Page 110
2nd para

"which pauses the program that is being run and properly allocated the memory" Not sure exactly what is technically correct here, but the change of tense here is not right. Perhaps "which pauses the program that is being run and properly allocates the memory" or "which pauses the program in order to properly allocate the memory"

Note from the Author or Editor:
Changed to: ... which pauses the program that is being run and properly allocates the memory.

dml  Jul 07, 2014 
PDF
Page 111
2nd para

"there will be less branch misses" --> "there will be fewer branch misses"

dml  Jul 08, 2014  Aug 21, 2014
PDF
Page 111
First two paras under "Making decisions with perf's output"

These two paragraphs feel like a bit of a letdown. The section is titled "Making decisions with perf", and we have just come out of a 3-1/2 page buildup explaining perf (starting from "Memory Fragmentation"). That buildup says, in part, "the perf tool can be used to get amazing amounts of insight..." So I enter this section with high hopes of using the perf output to really get some insight. Instead, there is a half-paragraph description of how perf's output shows the code has 30% cache misses, followed by another paragraph describing why those cache misses occur. It seems like a lot of build-up to just say, "Look at that one number; here's what it means." Furthermore, that description back-references a much earlier discussion, so it doesn't really feel like the insight is motivated by perf. In other words, you explain that one number from perf, using theory that you could have invoked right from the start. So without ever mentioning perf, you could still have said "We know that the lists are time-killers, because they induce memory fragmentation", and then jumped right into the optimization. There is also a bit of an organizational problem with the second half of the first paragraph (starting with "From this data we can see other things as well"). That second half mentions some other things perf shows about the current code, but those things aren't related to the optimization that follows. The problem with this is that the next paragraph starts out by saying "Fragmentation not only increases..." So organizationally, the discussion of memory fragmentation is broken up by a half-paragraph describing something completely unrelated. I do have a suggestion for what to do about all this. In a nutshell, I like all the material here, but feel like some of it is in the wrong place. Specifically, the discussion under "Understanding perf" is really valuable. However, it feels like it would fit much better in Chapter 2, which is much more tool-oriented. Following that idea a bit further, I wonder whether you might not do yourself a favor by slightly changing the focus of Chapter 2. It's largely about tools, and how to interpret their output, already. So maybe making it explicitly about tools will help the "flow" of the presentation. It would turn that chapter into a more technical guide to running the tools and reading their output, which can then be referenced when actually using the tools' output to guide optimization. The optimization bits that are in there could be pulled out into a shorter discussion, akin to what I'm advocating here. I feel like that would improve the current section, by allowing you to just say "Here's the code, here's perf's output (see Chapter 2 for a complete description). From the output, we see 30% cache misses. Where are those coming from?" In short, I feel like there's a lot of strong material here, but that the flow of the current discussion gets broken up too much by the digression explaining perf. So perhaps re-distributing that material throughout the book will help.

Note from the Author or Editor:
This section was restructured to hopefully have more flow. In addition, when we add numpy in order to act on the original perf output, I specifically call back to our observations.

dml  Jul 14, 2014 
PDF
Page 112
introduction of bumpy package

Looking at the paragraph that starts "Luckily, the numpy package..." Since this introduces numpy, and doesn't relate directly to "Making decisions with perf", you might consider starting a new section here. In fact, you might label such a new section "Enter numpy", and then rename the section that currently has that title (on p. 115) something like "Applying numpy to the diffusion problem". This would make plain that you're returning to the original, motivating, example. By page 115, it's been something like 8 pages since you touched the diffusion example, and a little reminder that that's what we're working on wouldn't be amiss.

Note from the Author or Editor:
As requested, a new subsection will start on page 115 and the subsequent section heading will have a more informative title.

dml  Jul 15, 2014 
PDF
Page 112
bird icon

The paragraph starting "Why doesn't the data..." could be more clear, in several ways. First of all, the second sentence is a little hard to parse. I think it's because that bit about "in a vectorized way versus a non-vectorized way use different parts of the CPU" makes you wade through a lot of setup before getting to the meat of the argument. Maybe something like "If we looked at the raw machine code that the CPU is running, multiplying two arrays in a vectorized way uses a different part of of the CPU, and different instructions, than multiplying them in a non-vectorized way." Or perhaps cut the first bit of the sentence and say "Multiplying two arrays in a vectorized way uses..." Second, "vectorized way versus non-vectorized way" is pretty vague. Maybe go more for the root cause? For example "A vectorized multiplication, in order to operate on multiple elements of the array at one time, requires using different CPU instructions than a sequential multiplication." Third, the "multiplying two arrays" example comes out of the blue. If you go back several pages, the context for this discussion is still the grid operations of the 2D diffusion problem. There are no inner products (which is what I assume you mean by "multiplying two arrays") in that example. So maybe just say "vectorized operations" rather than "a vectorized multiplication"? Or perhaps relate the example more to the grid? Or perhaps make the example the vector norm operation that you'll be using in the example that follows? Finally, I would also consider moving this bird-icon paragraph up one paragraph. Right now the flow is this: (1) Paragraph mentioning benefits of vectorization. (2) Paragraph mentioning implementation details of Python array type. (3) Paragraph (with bird icon) describing why vectorization isn't automatic. So switching (3) to come after (1) but before (2) would put things in a more straightforward sequence.

Note from the Author or Editor:
Rearranged and change reference to vectorized multiplication in favor of general "vectorized operations". Added sentences later that further connect the numpy norm example to these vectorized instructions.

dml  Jul 15, 2014 
PDF
Page 112
function norm_square_list_comprehension()

You give a dot-product implementation that uses a list comprehension: sum([v*v for v in vector]) Earlier in the book (chapter 5, see around p90), you talk about how generator comprehensions can relieve memory pressure. So it might be interesting to compare the timing also for a generator comprehension: sum((v*v for v in vector)) (Playing around in the REPL, it seems like the extra set of parens aren't needed.)

Note from the Author or Editor:
Good point! Example added (and it's 20% faster than the list comprehension).

dml  Jul 16, 2014 
PDF
Page 112
2nd para

"in a more efficiently in memory" --> "more efficiently in memory"

dml  Jul 14, 2014  Aug 21, 2014
PDF
Page 114
first para

"the array and pure python functions take ~100,000,000,000 instructions while the numpy version take ~3,000,000,000 instructions." First, "numpy version takes" (add 's') Second, consider using scientific notation for numbers, to make the difference more clear: "the array and pure python functions take ~1x10^{11} instructions while the numpy version take ~3x10^9 instructions."

Note from the Author or Editor:
Fixed grammatical mistake and changed to scientific notation (good call!).

dml  Jul 16, 2014 
PDF
Page 114
first para

"while numpy has \~55%" Remove extraneous escape character (\).

dml  Jul 16, 2014  Aug 21, 2014
PDF
Page 114
Fig 6-3

The titles in the legend do not match the function names (even accounting for the change from "norm_square" to "norm"). Might also be nice to change legend order. Either match order in which functions were presented, or (better yet) make order match that of the actual lines. This would be especially helpful because the distinction, in the graph itself, between the graphical styles of the norm_python and norm_python_comprehension lines is hard to make out. Consider getting a real en-dash or em-dash, rather than two hyphens, in the y-axis label ("Runtime - - less is better"). In the caption, "lenghts" --> "lengths"

Note from the Author or Editor:
I fixed this figure by having better legend names, adding the generator's timings and sorting the labels.

dml  Jul 16, 2014 
PDF
Page 114
first para

"In addition to lighter and more specialized machinery..." Not sure what "lighter" means in this context.

Note from the Author or Editor:
Changed to In addition to more lightweight and specialized machinery,

dml  Jul 16, 2014 
PDF
Page 115
para before Example 6-9

"using much simplified, vectorized, numpy arrays" You probably mean "simpler" rather than "simplified". The numpy arrays are perhaps simpler to use than Python arrays, but the numpy arrays aren't themselves simplified. This is more pedantic, but I don't think the arrays themselves are vectorized-- only the operations on the arrays. But it's probably not worth worrying about, since you make your point.

Note from the Author or Editor:
s/much simplified/simpler

dml  Jul 17, 2014 
PDF
Page 115
2nd para under "Enter numpy"

"substantially effect speed of the actual calculation" --> "substantially affect the speed of the calculation" - affect, not effect - add "the" - not sure what "actual" was referring to, or what it was supposed to clarify

dml  Jul 17, 2014  Aug 21, 2014
PDF
Page 117
1st para

"less instructions per cycle" --> "fewer instructions per cycle" Instructions are countable, so conventional usage is to say "fewer". Yes, you can find people on the web who argue that "less" is OK. This appears multiple places on this page (at least 3). By the way, later on in this sentence, "each of the instructions is able to do much more work" could be changed to "each of the instructions does much more work"-- to my ear, this sounds more direct and stronger.

Note from the Author or Editor:
s/less/fewer s/is able to do/does

dml  Jul 18, 2014 
PDF
Page 117
3rd para

"necissarily" --> "necessarily"

dml  Jul 18, 2014  Aug 21, 2014
PDF
Page 117
para before Example 6-11

There's a strange gap between the word "vectorization" and the superscript "1" for the footnote. As long as I'm leaving a comment about this paragraph, let me add a compliment. I have suggested a lot of changes, and I worry about sounding too critical. So I'll take this chance to comment on this excellent example. This is really a great numerical experiment, and it wasn't trivial to carry out-- you had to recompile numpy with the optimizations off, and that couldn't have been a simple 10-second test. I applaud your dedication, because the insight it gives is really nice. There is a lot of really good content in this book. Hopefully the authors understand that my comments are attempts to let the content shine.

dml  Jul 18, 2014  Aug 21, 2014
PDF
Page 118
1st para

"gives us a \~6x speedup" Remove the "\". This showed up earlier; I don't plan to mention this one again.

dml  Jul 18, 2014  Aug 21, 2014
PDF
Page 118
2nd para

"designed to exactly the calculation" You probably mean "designed to do exactly the calculation" Later in the same sentence, I would probably change "with the problem" to be "with this problem" (to emphasize which problem you mean).

dml  Jul 18, 2014  Aug 21, 2014
PDF
Page 119
Example 6-13

Looking at "%%timeit" Most places in the book use "%timeit" (one % sign). Here, and an example in chapter 3, there are two %% signs. Not sure if there's a distinction, or if this is a typo (I don't have IPython).

Note from the Author or Editor:
I added a note saying how %%timeit is different from %timeit (notably that it let's us specify setup code that isn't considering in the timings).

dml  Jul 21, 2014 
PDF
Page 119
Explication #3 of Example 6-12

"the memory address has change" --> "the memory address has changed" Also, farther down, "ie:" --> "i.e.,"

dml  Jul 21, 2014  Aug 21, 2014
PDF
Page 119
here and on next page

Sometimes you have "in-place", sometimes "in place", and sometimes "inplace". First one would be my preference, but just standardizing is the main thing.

dml  Jul 21, 2014  Aug 21, 2014
PDF
Page 120
Example 6-14

In this example, the variable name "scratch" implies that the array is only passed to function evolve() in order to give it some memory to work in (i.e., to avoid multiple allocations). But in fact, "scratch" returns useful information-- as shown by the "swap" operation. Consider choosing a name like "nextGrid" or "gridNext", that indicates the actual use (and if you do, remember to change the name in the surrounding text).

Note from the Author or Editor:
Good point. Renamed variable to "next_grid"

dml  Jul 21, 2014 
PDF
Page 120
Explication #1 of Example 6-14

"grid has the most updated information" --> "grid has the most up-to-date information" "grid has the most updated information" means that the memory currently referenced by "grid" has had more updates that that referenced by "scratch". What you want is for "grid" to reference the most recently-updated version of the diffusion results.

Note from the Author or Editor:
Changed to: ... grid has the most up-to-date information.

dml  Jul 21, 2014 
PDF
Page 122
1st para

"two main high level issue" --> "two main high-level issues"

dml  Jul 22, 2014  Aug 21, 2014
PDF
Page 126
1st para

"and tried so saturate" --> "and tries to saturate"

dml  Jul 23, 2014  Aug 21, 2014
PDF
Page 126
2nd para

"fit two 800x800 vectors" "vectors" --> "arrays" (or "grids")

Note from the Author or Editor:
s/vectors/arrays for consistency with previous sentences.

dml  Jul 23, 2014 
PDF
Page 126
1st para under "Cautionary tale"

"profile to the code" --> "profile the code"

dml  Jul 23, 2014  Aug 21, 2014
PDF
Page 126
1st para under "Cautionary tale"

"straight forward" --> "straightforward"

dml  Jul 23, 2014  Aug 21, 2014
PDF
Page 126
last para

"the fact that laplacians are a common operation" When used in text, "Laplacian" should be capitalized (lower-case when used as a function name is fine).

Note from the Author or Editor:
Changed to "Laplacians" without mono-space font.

dml  Jul 23, 2014 
PDF
Page 127
last para

"The increase page-faults" --> "The increased page-faults"

dml  Jul 23, 2014  Aug 21, 2014
PDF
Page 127
last para

"The increase page-faults shows us" I was a too hasty with last comment. This should be either: ""The increased page-faults show us" or: "The increase in page-faults shows us"

Note from the Author or Editor:
Changed to: The increase in page-faults shows us...

dml  Jul 23, 2014 
PDF
Page 131
Figure 6-4, legend

numexpr is missing an x (spelled 'numepr') next to the blue line

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014
PDF
Page 152
Example 7-10

Lacking Python syntax highlighting

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014
PDF
Page 170
Example 7-22

Lacking Python syntax highlighting

Note from the Author or Editor:
The lexer is not properly parsing this line, so it will not be highlighted.

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014
ePub
Page 172.0/330
United States

The function fibonacci_generator() has an error def fibonacci_generator(): count = 0 for f in fibonacci(): if f > 5000: break if j % 2: count += 1 return count In the second if statement, if j % 2: should be if f % 2:

Louis Luangkesorn  Jun 09, 2014 
ePub
Page 218.3/330
United States

Numerous locations For code examples, many of them are later referred to using a file name. For example Example 6-9 is later referrenced as diffusion_numpy.py in Example 6-10. For examples that are expected to be runnable, you should put its own file name in the example, one way to do this is to lead the example with a comment, like you do in some of the chapter 7 examples. Also, examples that are supposed to be files to be referenced later should be whole and runnable. e.g. put in a __main__ function. It would also make this much easier if the example code can be downloaded so anything from the command line can be run on them..

Note from the Author or Editor:
The code has been put online so that examples can easily be run.

lluang  Jul 09, 2014 
PDF
Page 232
Example 9-9

Lacking Python syntax highlighting

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014
PDF
Page 245
Example 9-20

Lacking Python syntax highlighting

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014
PDF
Page 247
Example 9-22

Lacking Python syntax highlighting

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014
PDF
Page 256
Example 9-33

Lacking Python syntax highlighting

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014
PDF
Page 259
1st para after "Locking a Value"

Sentence starts with a comma: ",The multiprocessing module".

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014
PDF
Page 260
Example 9-42

Lacking Python syntax highlighting

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014
PDF
Page 261
Example 9-45

Lacking Python syntax highlighting

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014
PDF
Page 272
Example 10-2

Lacking Python syntax highlighting

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014
PDF
Page 273
Example 10-4

Lacking Python syntax highlighting

Yury V. Zaytsev  Aug 11, 2014  Aug 21, 2014