4444.. code-block :: ipython3
4545
4646 In [3]: 0./0.
47- ---------------------------------------------------------------------------
48- ZeroDivisionError Traceback (most recent call last)
49- <ipython-input-3-4e5c12397e23> in <module>
47+ --------------------------------------------------------------------------
48+ ZeroDivisionError Traceback (most recent call last)
49+ Cell In [3], line 1
5050 ----> 1 0./0.
5151
5252 ZeroDivisionError: float division by zero
@@ -71,7 +71,7 @@ Now consider the case of an expression that doesn't make mathematical sense:
7171.. code-block :: ipython3
7272
7373 In [5]: 3 * %
74- File "<ipython-input-5-442f22cdc61f>" , line 1
74+ Cell In [5] , line 1
7575 3 * %
7676 ^
7777 SyntaxError: invalid syntax
@@ -164,9 +164,9 @@ of exception built in. For example, if we attempt to access the number
164164.. code-block :: ipython3
165165
166166 In [1]: (0, 1)[2]
167- ---------------------------------------------------------------------------
168- IndexError Traceback (most recent call last)
169- <ipython-input-1-def0bb43ba85> in <module>
167+ --------------------------------------------------------------------------
168+ IndexError Traceback (most recent call last)
169+ Cell In [1], line 1
170170 ----> 1 (0, 1)[2]
171171
172172 IndexError: tuple index out of range
@@ -202,7 +202,7 @@ the :class:`~polynomial.Polynomial` class from
202202
203203.. code-block :: ipython3
204204
205- In [1]: from polynomial import Polynomial
205+ In [1]: from example_code. polynomial import Polynomial
206206
207207 In [2]: p = Polynomial(("a", "b"))
208208
@@ -217,22 +217,24 @@ trouble:
217217.. code-block :: ipython3
218218
219219 In [4]: print(1 + p)
220- ---------------------------------------------------------------------------
221- TypeError Traceback (most recent call last)
222- <ipython-input-5-141816221609> in <module>
220+ --------------------------------------------------------------------------
221+ TypeError Traceback (most recent call last)
222+ Cell In [4], line 1
223223 ----> 1 print(1 + p)
224224
225- ~/docs/object-oriented-programming/src/polynomial.py in __radd__(self, other)
226- 57 def __radd__(self, other):
227- 58
228- ---> 59 return self + other
225+ File ~/docs/principles_of_programming/object-oriented-programming/example_code/polynomial.py:59, in Polynomial.__radd__(self, other)
226+ 58 def __radd__(self, other):
227+ ---> 59 return self + other
229228
230- ~/docs/object-oriented-programming/src/polynomial.py in __add__(self, other)
231- 38
232- 39 if isinstance(other, Number):
233- ---> 40 return Polynomial((self.coefficients[0] + other,) + self.coefficients[1:])
234- 41
235- 42 elif isinstance(other, Polynomial):
229+ File ~/docs/principles_of_programming/object-oriented-programming/example_code/polynomial.py:38, in Polynomial.__add__(self, other)
230+ 36 def __add__(self, other):
231+ 37 if isinstance(other, Number):
232+ ---> 38 return Polynomial((self.coefficients[0] + other,)
233+ 39 + self.coefficients[1:])
234+ 41 elif isinstance(other, Polynomial):
235+ 42 # Work out how many coefficient places the two polynomials have in
236+ 43 # common.
237+ 44 common = min(self.degree(), other.degree()) + 1
236238
237239 TypeError: can only concatenate str (not "int") to str
238240
@@ -304,22 +306,24 @@ Let's return to the traceback for our erroneous polynomial addition:
304306.. code-block :: ipython3
305307
306308 In [4]: print(1 + p)
307- ---------------------------------------------------------------------------
308- TypeError Traceback (most recent call last)
309- <ipython-input-5-141816221609> in <module>
309+ --------------------------------------------------------------------------
310+ TypeError Traceback (most recent call last)
311+ Cell In [4], line 1
310312 ----> 1 print(1 + p)
311313
312- ~/docs/object-oriented-programming/src/polynomial.py in __radd__(self, other)
313- 57 def __radd__(self, other):
314- 58
315- ---> 59 return self + other
314+ File ~/docs/principles_of_programming/object-oriented-programming/example_code/polynomial.py:59, in Polynomial.__radd__(self, other)
315+ 58 def __radd__(self, other):
316+ ---> 59 return self + other
316317
317- ~/docs/object-oriented-programming/src/polynomial.py in __add__(self, other)
318- 38
319- 39 if isinstance(other, Number):
320- ---> 40 return Polynomial((self.coefficients[0] + other,) + self.coefficients[1:])
321- 41
322- 42 elif isinstance(other, Polynomial):
318+ File ~/docs/principles_of_programming/object-oriented-programming/example_code/polynomial.py:38, in Polynomial.__add__(self, other)
319+ 36 def __add__(self, other):
320+ 37 if isinstance(other, Number):
321+ ---> 38 return Polynomial((self.coefficients[0] + other,)
322+ 39 + self.coefficients[1:])
323+ 41 elif isinstance(other, Polynomial):
324+ 42 # Work out how many coefficient places the two polynomials have in
325+ 43 # common.
326+ 44 common = min(self.degree(), other.degree()) + 1
323327
324328 TypeError: can only concatenate str (not "int") to str
325329
@@ -330,34 +334,32 @@ occurred. The traceback for this frame starts:
330334
331335.. code-block :: ipython3
332336
333- ~/docs/object-oriented-programming/src/polynomial.py in __add__(self, other)
334-
335- This indicates that the frame describes code in the file
336- `polynomial.py ` (which, on the author's computer, is located in the
337- folder `~~/docs/object-oriented-programming/src/ `). Specifically, the
338- stack frame describes the execution of the :meth: `__add__ ` method,
339- which is the :term: `special method ` responsible for polynomial
340- addition. The lines below this show the line on which execution
341- stopped (line 40, in this case) and a couple of lines on either side,
342- for context.
343-
344- The stack frame above this shows the function from which the
345- :meth: `__add__ ` method was called. In this case, this is the reverse
346- addition :term: `special method `, :meth: `__radd__ `. On line 59 :meth: `__radd__ ` calls
347- :meth: `__add__ ` through the addition of `self ` and `other `.
348-
349- Finally, the top stack frame corresponds to the command that the user
350- typed in iPython. This stack frame looks a little different from the
351- others. For starters, instead of the file name there is the string
352- `<ipython-input-5-141816221609> `. This is simply the :term: `Python
353- interpreter `'s internal name for a notional "file" containing one line
354- of iPython input. Similarly, because the line the user typed is not in
355- any function, the interpreter treats it as code written in the top
356- level of an unnamed module called `<module> `. Finally, because the
357- interpreter treats every line of input as a separate file, the call to
358- :meth: `__radd__ ` implementing the reverse addition of the number 1 to
359- the polynomial `p ` occurs on line 1 even though we are on the fourth
360- line of the iPython session.
337+ File ~/docs/principles_of_programming/object-oriented-programming/example_code/polynomial.py:38, in Polynomial.__add__(self, other)
338+
339+ This indicates that the frame describes code in the file `polynomial.py `
340+ (which, on the author's computer, is located in the folder
341+ `~~/principles_of_programming/object-oriented-programming/example_code/ `).
342+ Specifically, the stack frame describes the execution of the :meth: `__add__ `
343+ method, which is the :term: `special method ` responsible for polynomial
344+ addition. The lines below this show the line on which execution stopped (line
345+ 38, in this case) and a couple of lines on either side, for context.
346+
347+ The stack frame above this shows the function from which the :meth: `__add__ `
348+ method was called. In this case, this is the reverse addition :term: `special
349+ method `, :meth: `__radd__ `. On line 59 :meth: `__radd__ ` calls :meth: `__add__ `
350+ through the addition of `self ` and `other `.
351+
352+ Finally, the top stack frame corresponds to the command that the user typed in
353+ iPython. This stack frame looks a little different from the others. Instead of
354+ a file name there and a function name there is `Cell In [4], line 1 `. This
355+ indicates that the exception was raised on line 1 of the IPython cell `In [4] `.
356+
357+ .. hint ::
358+
359+ Older versions of Python display less helpful location information for the
360+ top stack frame, so in that case you might see something like
361+ `<ipython-input-2-c3aeb16193d4> in <module> ` rather than
362+ `Cell In [4], line 1 `.
361363
362364.. hint ::
363365
@@ -399,24 +401,32 @@ take a string argument, which is the error message to be printed. In
399401:numref: `typesafe_fib `, we inform the user that we were expecting an
400402integer rather than the type actually provided.
401403
404+ .. only :: book
405+
406+ .. raw :: latex
407+
408+ \clearpage
409+
410+
402411.. _typesafe_fib :
403412
404413.. code-block :: python3
405- :emphasize-lines: 6,7,8
414+ :emphasize-lines: 8,9,10
406415 :caption: A version of the Fibonacci function which raises an
407416 exception if a non-integer type is passed as the
408417 argument.
409418 :linenos:
410419
411-
412420 from numbers import Integral
413421
422+
414423 def typesafe_fib(n):
415424 """Return the n-th Fibonacci number, raising an exception if a
416425 non-integer is passed as n."""
417426 if not isinstance(n, Integral):
418427 raise TypeError(
419- f"fib expects an integer, not a {type(n).__name__}")
428+ f"fib expects an integer, not a {type(n).__name__}"
429+ )
420430 if n == 0:
421431 return 0
422432 elif n == 1:
@@ -429,19 +439,22 @@ If we now pass a non-integer value to this function, we observe the following:
429439
430440.. code-block :: ipython3
431441
432- In [1]: from fibonacci import typesafe_fib
442+ In [1]: from fibonacci.typesafe_fibonacci import typesafe_fib
433443 In [2]: typesafe_fib(1.5)
434- ---------------------------------------------------------------------------
435- TypeError Traceback (most recent call last)
436- <ipython-input-2-c3aeb16193d4> in <module>
444+ --------------------------------------------------------------------------
445+ TypeError Traceback (most recent call last)
446+ Cell In [2], line 1
437447 ----> 1 typesafe_fib(1.5)
438448
439- ~/docs/object-oriented-programming/fibonacci/fibonacci.py in typesafe_fib(n)
440- 14 non-integer is passed as n."""
441- 15 if not isinstance(n, Integral):
442- ---> 16 raise TypeError(
443- 17 f"fib expects an integer, not a {type(n).__name__}")
444- 18 if n == 0:
449+ File ~/docs/principles_of_programming/object-oriented-programming/fibonacci/typesafe_fibonacci.py:8, in typesafe_fib(n)
450+ 5 """Return the n-th Fibonacci number, raising an exception if a
451+ 6 non-integer is passed as n."""
452+ 7 if not isinstance(n, Integral):
453+ ----> 8 raise TypeError(
454+ 9 f"fib expects an integer, not a {type(n).__name__}"
455+ 10 )
456+ 11 if n == 0:
457+ 12 return 0
445458
446459 TypeError: fib expects an integer, not a float
447460
0 commit comments