diff --git a/advanced-iterators.html b/advanced-iterators.html index 472ae72..cd585dd 100755 --- a/advanced-iterators.html +++ b/advanced-iterators.html @@ -38,7 +38,7 @@ S = 6 T = 2 E = 4 -
Puzzles like this are called cryptarithms or alphametics. The letters spell out actual words, but if you replace each letter with a digit from 0–9, it also “spells” an arithmetic equation. The trick is to figure out which letter maps to each digit. All the occurrences of each letter must map to the same digit, no digit can be repeated, and no “word” can start with the digit 0.
+
Puzzles like this are called cryptarithms or alphametics. The letters spell out actual words, but if you replace each letter with a digit from 0–9, it also “spells” an arithmetic equation. The trick is to figure out which letter maps to each digit. All the occurrences of each letter must map to the same digit, no digit can be repeated, and no “word” can start with the digit 0.
The most well-known alphametic puzzle is SEND + MORE = MONEY.
diff --git a/comprehensions.html b/comprehensions.html
index b0a7c07..2d3b11e 100644
--- a/comprehensions.html
+++ b/comprehensions.html
@@ -334,7 +334,7 @@ body{counter-reset:h1 3}
{32, 1, 2, 4, 8, 64, 128, 256, 16, 512}
0 to 9.
+9.
if clause to filter each item before returning it in the result set.
0 and 1, goes up slowly at first, then more and more rapidly. To start the sequence, you need two variables: a starts at 0, and b starts at 1.
+1, goes up slowly at first, then more and more rapidly. To start the sequence, you need two variables: a starts at 0, and b starts at 1.
a + b) and assign that to b for later use. Note that this happens in parallel; if a is 3 and b is 5, then a, b = b, a + b will set a to 5 (the previous value of b) and b to 8 (the sum of the previous values of a and b).
For example, take this snippet from humansize.py:
if size < 0:
raise ValueError('number must be non-negative')
-size is an integer, 0 is an integer, and < is a numerical operator. The result of the expression size < 0 is always a boolean. You can test this yourself in the Python interactive shell:
+
size is an integer, 0 is an integer, and < is a numerical operator. The result of the expression size < 0 is always a boolean. You can test this yourself in the Python interactive shell:
>>> size = 1
>>> size < 0
@@ -53,7 +53,7 @@ body{counter-reset:h1 2}
>>> size = -1
>>> size < 0
True
-Due to some legacy issues left over from Python 2, booleans can be treated as numbers. True is 1; False is 0.
+
Due to some legacy issues left over from Python 2, booleans can be treated as numbers. True is 1; False is 0.
>>> True + True 2 @@ -107,7 +107,7 @@ ZeroDivisionError: int division or modulo by zero
int to a float by calling the float() function.
float to an int by calling int().
int() function will truncate, not round.
-int() function truncates negative numbers towards 0. It’s a true truncate function, not a a floor function.
+int() function truncates negative numbers towards 0. It’s a true truncate function, not a a floor function.
/ operator performs floating point division. It returns a float even if both the numerator and denominator are ints.
-// operator performs a quirky kind of integer division. When the result is positive, you can think of it as truncating (not rounding) to 0 decimal places, but be careful with that.
+// operator performs a quirky kind of integer division. When the result is positive, you can think of it as truncating (not rounding) to 0 decimal places, but be careful with that.
// operator rounds “up” to the nearest integer. Mathematically speaking, it’s rounding “down” since −6 is less than −5, but it could trip you up if you expecting it to truncate to −5.
// operator doesn’t always return an integer. If either the numerator or denominator is a float, it will still round to the nearest integer, but the actual return value will be a float.
** operator means “raised to the power of.” 112 is 121.
@@ -207,8 +207,8 @@ ZeroDivisionError: Fraction(0, 0)
no, it's false
0 is false.
-0.0 is false. Be careful with this one! If there’s the slightest rounding error (not impossible, as you saw in the previous section) then Python will be testing 0.0000000000001 instead of 0 and will return True.
+0.0 is false. Be careful with this one! If there’s the slightest rounding error (not impossible, as you saw in the previous section) then Python will be testing 0.0000000000001 instead of 0 and will return True.
Fraction(0, n) is false for all values of n. All other fractions are true.
⁂ @@ -264,7 +264,7 @@ ZeroDivisionError: Fraction(0, 0)
a_list[1]), up to but not including the second slice index (in this case a_list[3]).
a_list[0:3] returns the first three items of the list, starting at a_list[0], up to but not including a_list[3].
-0, you can leave it out, and 0 is implied. So a_list[:3] is the same as a_list[0:3], because the starting 0 is implied.
+a_list[:3] is the same as a_list[0:3], because the starting 0 is implied.
a_list[3:] is the same as a_list[3:5], because this list has five items. There is a pleasing symmetry here. In this five-item list, a_list[:3] returns the first 3 items, and a_list[3:] returns the last two items. In fact, a_list[:n] will always return the first n items, and a_list[n:] will return the rest, regardless of the length of the list.
a_list[:] is shorthand for making a complete copy of a list.
count() method returns the number of occurrences of a specific value in a list.
in operator is slightly faster than using the count() method. The in operator always returns True or False; it will not tell you where in the list the value is.
-index() method. By default it will search the entire list, although you can specify a second argument of the (0-based) index to start from, and even a third argument of the (0-based) index to stop searching.
+index() method. By default it will search the entire list, although you can specify a second argument of the (0-based) index to start from, and even a third argument of the (0-based) index to stop searching.
index() method finds the first occurrence of a value in the list. In this case, 'new' occurs twice in the list, in a_list[2] and a_list[4], but the index() method will return only the index of the first occurrence.
index() method will raise an exception.
range() function constructs a sequence of integers. (Technically, the range() function returns an iterator, not a list or a tuple, but you’ll learn about that distinction later.) MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, and SUNDAY are the variables you’re defining. (This example came from the calendar module, a fun little module that prints calendars, like the UNIX program cal. The calendar module defines integer constants for days of the week.)
-0, TUESDAY is 1, and so forth.
+1, and so forth.
You can also use multi-variable assignment to build functions that return multiple values, simply by returning a tuple of all the values. The caller can treat it as a single tuple, or it can assign the values to individual variables. Many standard Python libraries do this, including the os module, which you'll learn about in the next chapter.
@@ -909,7 +909,7 @@ KeyError: 'db.diveintopython3.org'
⁂
NoneNone is a special constant in Python. It is a null value. None is not the same as False. None is not 0. None is not an empty string. Comparing None to anything other than None will always return False.
+
None is a special constant in Python. It is a null value. None is not the same as False. None is not 0. None is not an empty string. Comparing None to anything other than None will always return False.
None is the only null value. It has its own datatype (NoneType). You can assign None to any variable, but you can not create other NoneType objects. All variables whose value is None are equal to each other.
>>> type(None) diff --git a/porting-code-to-python-3-with-2to3.html b/porting-code-to-python-3-with-2to3.html index 73c0224..fc78df2 100644 --- a/porting-code-to-python-3-with-2to3.html +++ b/porting-code-to-python-3-with-2to3.html @@ -1315,7 +1315,7 @@ except:Common idioms (explicit)
-There were a number of common idioms built up in the Python community. Some, like the
while 1:loop, date back to Python 1. (Python didn’t have a true boolean type until version 2.3, so developers used1and0instead.) Modern Python programmers should train their brains to use modern versions of these idioms instead. +There were a number of common idioms built up in the Python community. Some, like the
while 1:loop, date back to Python 1. (Python didn’t have a true boolean type until version 2.3, so developers used1and 0 instead.) Modern Python programmers should train their brains to use modern versions of these idioms instead.☞The
2to3script will not fix common idioms by default. To enable this fix, specify -f idioms on the command line when you call2to3. diff --git a/regular-expressions.html b/regular-expressions.html index 8e8b4ce..b1b69ec 100755 --- a/regular-expressions.html +++ b/regular-expressions.html @@ -311,7 +311,7 @@ body{counter-reset:h1 5} File "<stdin>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'groups'
(\d{3}). What’s \d{3}? Well, \d means “any numeric digit” (0 through 9). The {3} means “match exactly three numeric digits”; it’s a variation on the {n,m} syntax you saw earlier. Putting it all in parentheses means “match exactly three numeric digits, and then remember them as a group that I can ask for later”. Then match a literal hyphen. Then match another group of exactly three digits. Then another literal hyphen. Then another group of exactly four digits. Then match the end of the string.
+(\d{3}). What’s \d{3}? Well, \d means “any numeric digit” (0 through 9). The {3} means “match exactly three numeric digits”; it’s a variation on the {n,m} syntax you saw earlier. Putting it all in parentheses means “match exactly three numeric digits, and then remember them as a group that I can ask for later”. Then match a literal hyphen. Then match another group of exactly three digits. Then another literal hyphen. Then another group of exactly four digits. Then match the end of the string.
groups() method on the object that the search() method returns. It will return a tuple of however many groups were defined in the regular expression. In this case, you defined three groups, one with three digits, one with three digits, and one with four digits.
search() and groups() methods in production code. If the search() method returns no matches, it returns None, not a regular expression match object. Calling None.groups() raises a perfectly obvious exception: None doesn’t have a groups() method. (Of course, it’s slightly less obvious when you get this exception from deep within your code. Yes, I speak from experience here.)
diff --git a/special-method-names.html b/special-method-names.html
index 4b6187c..43b9c1b 100644
--- a/special-method-names.html
+++ b/special-method-names.html
@@ -614,7 +614,7 @@ class FieldStorage:
math.floor(x)
x.__floor__()
x to nearest integer toward 0
+x to nearest integer toward 0
math.trunc(x)
x.__trunc__()
hash(x)
x.__hash__()
x.color
type(x).__dict__['color'].__get__(x, type(x))
x.color = 'PapayaWhip'
type(x).__dict__['color'].__set__(x, 'PapayaWhip')
del x.color
type(x).__dict__['color'].__del__(x)
a_string[0]), up to but not including the second slice index (in this case a_string[2]).
a_string[0:3] returns the first three items of the string, starting at a_string[0], up to but not including a_string[3].
-0, you can leave it out, and 0 is implied. So a_string[:18] is the same as a_string[0:18], because the starting 0 is implied.
+a_string[:18] is the same as a_string[0:18], because the starting 0 is implied.
a_string[18:] is the same as a_string[18:44], because this string has 44 characters. There is a pleasing symmetry here. In this 44-character string, a_string[:18] returns the first 18 characters, and a_string[18:] returns everything but the first 18 characters. In fact, a_string[:n] will always return the first n characters, and a_string[n:] will return the rest, regardless of the length of the string.
diff --git a/unit-testing.html b/unit-testing.html
index 2ffc112..9a91c05 100755
--- a/unit-testing.html
+++ b/unit-testing.html
@@ -26,7 +26,7 @@ body{counter-reset:h1 9}
1 through 3999. The Romans did have several ways of expressing larger numbers, for instance by having a bar over a numeral to represent that its normal value should be multiplied by 1000. For the purposes of this chapter, let’s stipulate that Roman numerals go from 1 to 3999.
-0 in Roman numerals.
+Along with testing numbers that are too large, you need to test numbers that are too small. As we noted in our functional requirements, Roman numerals cannot express 0 or negative numbers.
+
Along with testing numbers that are too large, you need to test numbers that are too small. As we noted in our functional requirements, Roman numerals cannot express 0 or negative numbers.
>>> import roman2 @@ -376,7 +376,7 @@ OKself.assertRaises(roman3.OutOfRangeError, roman3.to_roman, -1) ③
test_too_large() method has not changed since the previous step. I’m including it here to show where the new code fits.
-test_zero() method. Like the test_too_large() method, it tells the assertRaises() method defined in unittest.TestCase to call our to_roman() function with a parameter of 0, and check that it raises the appropriate exception, OutOfRangeError.
+test_zero() method. Like the test_too_large() method, it tells the assertRaises() method defined in unittest.TestCase to call our to_roman() function with a parameter of 0, and check that it raises the appropriate exception, OutOfRangeError.
test_negative() method is almost identical, except it passes -1 to the to_roman() function. If either of these new tests does not raise an OutOfRangeError (either because the function returns an actual value, or because it raises some other exception), the test is considered failed.
Converting a string from a Roman numeral to an integer sounds more difficult than converting an integer to a Roman numeral. Certainly there is the issue of validation. It’s easy to check if an integer is greater than 0, but a bit harder to check whether a string is a valid Roman numeral. But we already constructed a regular expression to check for Roman numerals, so that part is done.
+
Converting a string from a Roman numeral to an integer sounds more difficult than converting an integer to a Roman numeral. Certainly there is the issue of validation. It’s easy to check if an integer is greater than 0, but a bit harder to check whether a string is a valid Roman numeral. But we already constructed a regular expression to check for Roman numerals, so that part is done.
That leaves the problem of converting the string itself. As we’ll see in a minute, thanks to the rich data structure we defined to map individual Roman numerals to integer values, the nitty-gritty of the from_roman() function is as straightforward as the to_roman() function.
diff --git a/xml.html b/xml.html
index 5ec8fff..c774a44 100755
--- a/xml.html
+++ b/xml.html
@@ -320,9 +320,9 @@ mark{display:inline}
{}
attrib property is a dictionary of the element’s attributes. The original markup here was <feed xmlns='http://www.w3.org/2005/Atom' xml:lang='en'>. The xml: prefix refers to a built-in namespace that every XML document can use without declaring it.
-[4] in a 0-based list — is the link element.
+[4] in a 0-based list — is the link element.
link element has three attributes: href, type, and rel.
-[3] in a 0-based list — is the updated element.
+[3] in a 0-based list — is the updated element.
updated element has no attributes, so its .attrib is just an empty dictionary.
-☞There is a “gotcha” with the
find()method that will eventually bite you. In a boolean context, ElementTree element objects will evaluate toFalseif they contain no children (i.e. iflen(element)is0). This means thatif element.find('...')is not testing whether thefind()method found a matching element; it’s testing whether that matching element has any child elements! To test whether thefind()method returned an element, useif element.find('...') is not None. +☞There is a “gotcha” with the
find()method that will eventually bite you. In a boolean context, ElementTree element objects will evaluate toFalseif they contain no children (i.e. iflen(element)is 0). This means thatif element.find('...')is not testing whether thefind()method found a matching element; it’s testing whether that matching element has any child elements! To test whether thefind()method returned an element, useif element.find('...') is not None.
There is a way to search for descendant elements, i.e. children, grandchildren, and any element at any nesting level.