Skip to content

Commit a1cd757

Browse files
committed
update fibonacci
1 parent 5148d90 commit a1cd757

File tree

3 files changed

+104
-91
lines changed

3 files changed

+104
-91
lines changed

doc/source/6_exceptions.rst

Lines changed: 88 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ error:
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
400402
integer 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

fibonacci/fibonacci.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
from numbers import Integral
2-
3-
41
def fib(n):
52
"""Return the n-th Fibonacci number."""
63
if n == 0:
@@ -9,16 +6,3 @@ def fib(n):
96
return 1
107
else:
118
return fib(n-2) + fib(n-1)
12-
13-
14-
def typesafe_fib(n):
15-
"""Return the n-th Fibonacci number, raising an exception if a
16-
non-integer is passed as n."""
17-
if not isinstance(n, Integral):
18-
raise TypeError(f"fib expects an integer, not a {type(n).__name__}")
19-
if n == 0:
20-
return 0
21-
elif n == 1:
22-
return 1
23-
else:
24-
return fib(n-2) + fib(n-1)

fibonacci/typesafe_fibonacci.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from numbers import Integral
2+
3+
4+
def typesafe_fib(n):
5+
"""Return the n-th Fibonacci number, raising an exception if a
6+
non-integer is passed as n."""
7+
if not isinstance(n, Integral):
8+
raise TypeError(
9+
f"fib expects an integer, not a {type(n).__name__}"
10+
)
11+
if n == 0:
12+
return 0
13+
elif n == 1:
14+
return 1
15+
else:
16+
return fib(n-2) + fib(n-1)

0 commit comments

Comments
 (0)