mirror of
https://github.com/kennethreitz/dive-into-python3.git
synced 2026-06-05 15:00:18 +00:00
various corrections
This commit is contained in:
+6
-4
@@ -618,6 +618,8 @@ FAILED (errors=2)</samp></pre>
|
|||||||
def from_roman(s):
|
def from_roman(s):
|
||||||
'''convert Roman numeral to integer'''</code></pre>
|
'''convert Roman numeral to integer'''</code></pre>
|
||||||
|
|
||||||
|
<p>(Hey, did you notice that? I defined a function with nothing but a <a href=your-first-python-program.html#docstrings>docstring</a>. That’s legal Python. In fact, some programmers swear by it. “Don’t stub; document!”)
|
||||||
|
|
||||||
<p>Now the test cases will actually fail.
|
<p>Now the test cases will actually fail.
|
||||||
|
|
||||||
<pre class='nd screen'>
|
<pre class='nd screen'>
|
||||||
@@ -706,11 +708,11 @@ OK</samp></pre>
|
|||||||
<p>As you saw in <a href=regular-expressions.html#romannumerals>Case Study: Roman Numerals</a>, there are several simple rules for constructing a Roman numeral, using the letters <code>M</code>, <code>D</code>, <code>C</code>, <code>L</code>, <code>X</code>, <code>V</code>, and <code>I</code>. Let's review the rules:
|
<p>As you saw in <a href=regular-expressions.html#romannumerals>Case Study: Roman Numerals</a>, there are several simple rules for constructing a Roman numeral, using the letters <code>M</code>, <code>D</code>, <code>C</code>, <code>L</code>, <code>X</code>, <code>V</code>, and <code>I</code>. Let's review the rules:
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<li>Characters are additive. <code>I</code> is <code>1</code>, <code>II</code> is <code>2</code>, and <code>III</code> is <code>3</code>. <code>VI</code> is <code>6</code> (literally, “<code>5</code> and <code>1</code>”), <code>VII</code> is <code>7</code>, and <code>VIII</code> is <code>8</code>.
|
<li>Sometimes characters are additive. <code>I</code> is <code>1</code>, <code>II</code> is <code>2</code>, and <code>III</code> is <code>3</code>. <code>VI</code> is <code>6</code> (literally, “<code>5</code> and <code>1</code>”), <code>VII</code> is <code>7</code>, and <code>VIII</code> is <code>8</code>.
|
||||||
<li>The tens characters (<code>I</code>, <code>X</code>, <code>C</code>, and <code>M</code>) can be repeated up to three times. At <code>4</code>, you need to subtract from the next highest fives character. You can't represent <code>4</code> as <code>IIII</code>; instead, it is represented as <code>IV</code> (“<code>1</code> less than <code>5</code>”). <code>40</code> is written as <code>XL</code> (“<code>10</code> less than <code>50</code>”), <code>41</code> as <code>XLI</code>, <code>42</code> as <code>XLII</code>, <code>43</code> as <code>XLIII</code>, and then <code>44</code> as <code>XLIV</code> (“<code>10</code> less than <code>50</code>, then <code>1</code> less than <code>5</code>”).
|
<li>The tens characters (<code>I</code>, <code>X</code>, <code>C</code>, and <code>M</code>) can be repeated up to three times. At <code>4</code>, you need to subtract from the next highest fives character. You can't represent <code>4</code> as <code>IIII</code>; instead, it is represented as <code>IV</code> (“<code>1</code> less than <code>5</code>”). <code>40</code> is written as <code>XL</code> (“<code>10</code> less than <code>50</code>”), <code>41</code> as <code>XLI</code>, <code>42</code> as <code>XLII</code>, <code>43</code> as <code>XLIII</code>, and then <code>44</code> as <code>XLIV</code> (“<code>10</code> less than <code>50</code>, then <code>1</code> less than <code>5</code>”).
|
||||||
<li>Similarly, at <code>9</code>, you need to subtract from the next highest tens character: <code>8</code> is <code>VIII</code>, but <code>9</code> is <code>IX</code> (“<code>1</code> less than <code>10</code>”), not <code>VIIII</code> (since the <code>I</code> character can not be repeated four times). <code>90</code> is <code>XC</code>, <code>900</code> is <code>CM</code>.
|
<li>Sometimes characters are… the opposite of additive. By putting certain characters before others, you subtract from the final value. For example, at <code>9</code>, you need to subtract from the next highest tens character: <code>8</code> is <code>VIII</code>, but <code>9</code> is <code>IX</code> (“<code>1</code> less than <code>10</code>”), not <code>VIIII</code> (since the <code>I</code> character can not be repeated four times). <code>90</code> is <code>XC</code>, <code>900</code> is <code>CM</code>.
|
||||||
<li>The fives characters can not be repeated. <code>10</code> is always represented as <code>X</code>, never as <code>VV</code>. <code>100</code> is always <code>C</code>, never <code>LL</code>.
|
<li>The fives characters can not be repeated. <code>10</code> is always represented as <code>X</code>, never as <code>VV</code>. <code>100</code> is always <code>C</code>, never <code>LL</code>.
|
||||||
<li>Roman numerals are always written highest to lowest, and read left to right, so order of characters matters very much. <code>DC</code> is <code>600</code>; <code>CD</code> is a completely different number (<code>400</code>, “<code>100</code> less than <code>500</code>”). <code>CI</code> is <code>101</code>; <code>IC</code> is not even a valid Roman numeral (because you can't subtract <code>1</code> directly from <code>100</code>; you would need to write it as <code>XCIX</code>, “<code>10</code> less than <code>100</code>, then <code>1</code> less than <code>10</code>”).
|
<li>Roman numerals are read left to right, so the order of characters matters very much. <code>DC</code> is <code>600</code>; <code>CD</code> is a completely different number (<code>400</code>, “<code>100</code> less than <code>500</code>”). <code>CI</code> is <code>101</code>; <code>IC</code> is not even a valid Roman numeral (because you can't subtract <code>1</code> directly from <code>100</code>; you would need to write it as <code>XCIX</code>, “<code>10</code> less than <code>100</code>, then <code>1</code> less than <code>10</code>”).
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<p>Thus, one useful test would be to ensure that the <code>from_roman()</code> function should fail when you pass it a string with too many repeated numerals. How many is “too many” depends on the numeral.
|
<p>Thus, one useful test would be to ensure that the <code>from_roman()</code> function should fail when you pass it a string with too many repeated numerals. How many is “too many” depends on the numeral.
|
||||||
@@ -728,7 +730,7 @@ OK</samp></pre>
|
|||||||
for s in ('CMCM', 'CDCD', 'XCXC', 'XLXL', 'IXIX', 'IVIV'):
|
for s in ('CMCM', 'CDCD', 'XCXC', 'XLXL', 'IXIX', 'IVIV'):
|
||||||
self.assertRaises(roman6.InvalidRomanNumeralError, roman6.from_roman, s)</code></pre>
|
self.assertRaises(roman6.InvalidRomanNumeralError, roman6.from_roman, s)</code></pre>
|
||||||
|
|
||||||
<p>A third test could check that numerals appear in the correct order, from highest to lowest value. For example, <code>CL</code> is <code>150</code>, but <code>LC</code> is never valid, because the numeral for <code>50</code> can never come before the numeral for <code>100</code>.
|
<p>A third test could check that numerals appear in the correct order, from highest to lowest value. For example, <code>CL</code> is <code>150</code>, but <code>LC</code> is never valid, because the numeral for <code>50</code> can never come before the numeral for <code>100</code>. This test includes a randomly chosen set of invalid antecedents: <code>I</code> before <code>M</code>, <code>V</code> before <code>X</code>, and so on.
|
||||||
|
|
||||||
<pre class=nd><code class=pp> def test_malformed_antecedents(self):
|
<pre class=nd><code class=pp> def test_malformed_antecedents(self):
|
||||||
'''from_roman should fail with malformed antecedents'''
|
'''from_roman should fail with malformed antecedents'''
|
||||||
|
|||||||
Reference in New Issue
Block a user