Skip to content

Commit f71480d

Browse files
Update debugging lesson (#740)
1 parent f5b285b commit f71480d

File tree

3 files changed

+97
-92
lines changed

3 files changed

+97
-92
lines changed

advanced/debugging/index.rst

Lines changed: 93 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,6 @@ Here we debug the file :download:`index_error.py`. When running it, an
250250
251251
IndexError: list index out of range
252252
253-
In [61]: :q
254-
Cell In[61], line 1
255-
:q
256-
^
257-
SyntaxError: invalid syntax
258-
259253
In [2]: %debug
260254
> /home/jarrod/src/scientific-python-lectures/advanced/debugging/index_error.py(6)index_error()
261255
4 def index_error():
@@ -278,7 +272,7 @@ Here we debug the file :download:`index_error.py`. When running it, an
278272
279273
ipdb> len(lst)
280274
6
281-
ipdb> print(lst[len(lst)-1])
275+
ipdb> print(lst[len(lst) - 1])
282276
r
283277
ipdb> quit
284278
@@ -289,25 +283,26 @@ Here we debug the file :download:`index_error.py`. When running it, an
289283
you can call the script with ``python -m pdb script.py``::
290284

291285
$ python -m pdb index_error.py
292-
> /home/varoquau/dev/scientific-python-lectures/advanced/optimizing/index_error.py(1)<module>()
286+
> /home/jarrod/src/scientific-python-lectures/advanced/debugging/index_error.py(1)<module>()
293287
-> """Small snippet to raise an IndexError."""
294288
(Pdb) continue
295289
Traceback (most recent call last):
296-
File "/usr/lib/python2.6/pdb.py", line 1296, in main
297-
pdb._runscript(mainpyfile)
298-
File "/usr/lib/python2.6/pdb.py", line 1215, in _runscript
299-
self.run(statement)
300-
File "/usr/lib/python2.6/bdb.py", line 372, in run
301-
exec cmd in globals, locals
302-
File "<string>", line 1, in <module>
303-
File "index_error.py", line 8, in <module>
290+
File "/usr/lib64/python3.11/pdb.py", line 1793, in main
291+
pdb._run(target)
292+
File "/usr/lib64/python3.11/pdb.py", line 1659, in _run
293+
self.run(target.code)
294+
File "/usr/lib64/python3.11/bdb.py", line 600, in run
295+
exec(cmd, globals, locals)
296+
File "<string>", line 1, in <module>
297+
File "/home/jarrod/src/scientific-python-lectures/advanced/debugging/index_error.py", line 10, in <module>
304298
index_error()
305-
File "index_error.py", line 5, in index_error
306-
print lst[len(lst)]
299+
File "/home/jarrod/src/scientific-python-lectures/advanced/debugging/index_error.py", line 6, in index_error
300+
print(lst[len(lst)])
301+
~~~^^^^^^^^^^
307302
IndexError: list index out of range
308303
Uncaught exception. Entering post mortem debugging
309304
Running 'cont' or 'step' will restart the program
310-
> /home/varoquau/dev/scientific-python-lectures/advanced/optimizing/index_error.py(5)index_error()
305+
> /home/jarrod/src/scientific-python-lectures/advanced/debugging/index_error.py(6)index_error()
311306
-> print(lst[len(lst)])
312307
(Pdb)
313308

@@ -328,36 +323,40 @@ Indeed the code runs, but the filtering does not work well.
328323
*** Blank or comment
329324
*** Blank or comment
330325
*** Blank or comment
331-
*** Blank or comment
332326
NOTE: Enter 'c' at the ipdb> prompt to continue execution.
333327
> /home/jarrod/src/scientific-python-lectures/advanced/debugging/wiener_filtering.py(1)<module>()
334-
----> 1 """ Wiener filtering a noisy raccoon face: this module is buggy
335-
2 """
336-
3
337-
4 import numpy as np
338-
5 import scipy as sp
328+
----> 1 """Wiener filtering a noisy raccoon face: this module is buggy"""
329+
2
330+
3 import numpy as np
331+
4 import scipy as sp
332+
5 import matplotlib.pyplot as plt
339333
340-
* Set a break point at line 34 using ``b 34``:
334+
* Set a break point at line 29 using ``b 29``:
341335

342336
.. code-block:: ipython
343337
344338
ipdb> n
345-
> /home/varoquau/dev/scientific-python-lectures/advanced/optimizing/wiener_filtering.py(4)<module>()
346-
3
347-
1---> 4 import numpy as np
348-
5 import scipy as sp
349-
ipdb> b 34
350-
Breakpoint 2 at /home/varoquau/dev/scientific-python-lectures/advanced/optimizing/wiener_filtering.py:34
339+
> /home/jarrod/src/scientific-python-lectures/advanced/debugging/wiener_filtering.py(3)<module>()
340+
1 """Wiener filtering a noisy raccoon face: this module is buggy"""
341+
2
342+
----> 3 import numpy as np
343+
4 import scipy as sp
344+
5 import matplotlib.pyplot as plt
345+
346+
ipdb> b 29
347+
Breakpoint 1 at /home/jarrod/src/scientific-python-lectures/advanced/debugging/wiener_filtering.py:29
351348
352349
* Continue execution to next breakpoint with ``c(ont(inue))``:
353350

354351
.. code-block:: ipython
355352
356353
ipdb> c
357-
> /home/varoquau/dev/scientific-python-lectures/advanced/optimizing/wiener_filtering.py(34)iterated_wiener()
358-
33 """
359-
2--> 34 noisy_img = noisy_img
360-
35 denoised_img = local_mean(noisy_img, size=size)
354+
> /home/jarrod/src/scientific-python-lectures/advanced/debugging/wiener_filtering.py(29)iterated_wiener()
355+
27 Do not use this: this is crappy code to demo bugs!
356+
28 """
357+
1--> 29 noisy_img = noisy_img
358+
30 denoised_img = local_mean(noisy_img, size=size)
359+
31 l_var = local_var(noisy_img, size=size)
361360
362361
* Step into code with ``n(ext)`` and ``s(tep)``: ``next`` jumps to the next
363362
statement in the current execution context, while ``step`` will go across
@@ -366,34 +365,41 @@ Indeed the code runs, but the filtering does not work well.
366365
.. code-block:: ipython
367366
368367
ipdb> s
369-
> /home/varoquau/dev/scientific-python-lectures/advanced/optimizing/wiener_filtering.py(35)iterated_wiener()
370-
2 34 noisy_img = noisy_img
371-
---> 35 denoised_img = local_mean(noisy_img, size=size)
372-
36 l_var = local_var(noisy_img, size=size)
373-
ipdb> n
374-
> /home/varoquau/dev/scientific-python-lectures/advanced/optimizing/wiener_filtering.py(36)iterated_wiener()
375-
35 denoised_img = local_mean(noisy_img, size=size)
376-
---> 36 l_var = local_var(noisy_img, size=size)
377-
37 for i in range(3):
368+
> /home/jarrod/src/scientific-python-lectures/advanced/debugging/wiener_filtering.py(30)iterated_wiener()
369+
28 """
370+
1 29 noisy_img = noisy_img
371+
---> 30 denoised_img = local_mean(noisy_img, size=size)
372+
31 l_var = local_var(noisy_img, size=size)
373+
32 for i in range(3):
378374
375+
ipdb> n
376+
> /home/jarrod/src/scientific-python-lectures/advanced/debugging/wiener_filtering.py(31)iterated_wiener()
377+
1 29 noisy_img = noisy_img
378+
30 denoised_img = local_mean(noisy_img, size=size)
379+
---> 31 l_var = local_var(noisy_img, size=size)
380+
32 for i in range(3):
381+
33 res = noisy_img - denoised_img
379382
380383
* Step a few lines and explore the local variables:
381384

382385
.. code-block:: ipython
383386
384387
ipdb> n
385-
> /home/varoquau/dev/scientific-python-lectures/advanced/optimizing/wiener_filtering.py(37)iterated_wiener()
386-
36 l_var = local_var(noisy_img, size=size)
387-
---> 37 for i in range(3):
388-
38 res = noisy_img - denoised_img
388+
> /home/jarrod/src/scientific-python-lectures/advanced/debugging/wiener_filtering.py(32)iterated_wiener()
389+
30 denoised_img = local_mean(noisy_img, size=size)
390+
31 l_var = local_var(noisy_img, size=size)
391+
---> 32 for i in range(3):
392+
33 res = noisy_img - denoised_img
393+
34 noise = (res**2).sum() / res.size
394+
389395
ipdb> print(l_var)
390-
[[5868 5379 5316 ..., 5071 4799 5149]
391-
[5013 363 437 ..., 346 262 4355]
392-
[5379 410 344 ..., 392 604 3377]
393-
...,
394-
[ 435 362 308 ..., 275 198 1632]
395-
[ 548 392 290 ..., 248 263 1653]
396-
[ 466 789 736 ..., 1835 1725 1940]]
396+
[[2571 2782 3474 ... 3008 2922 3141]
397+
[2105 708 475 ... 469 354 2884]
398+
[1697 420 645 ... 273 236 2517]
399+
...
400+
[2437 345 432 ... 413 387 4188]
401+
[2598 179 247 ... 367 441 3909]
402+
[2808 2525 3117 ... 4413 4454 4385]]
397403
ipdb> print(l_var.min())
398404
0
399405
@@ -408,38 +414,34 @@ doing integer arithmetic.
408414
.. code-block:: ipython
409415
410416
In [2]: %run wiener_filtering.py
411-
wiener_filtering.py:40: RuntimeWarning: divide by zero encountered in divide
412-
noise_level = (1 - noise/l_var )
413-
417+
/home/jarrod/src/scientific-python-lectures/advanced/debugging/wiener_filtering.py:35: RuntimeWarning: divide by zero encountered in divide
418+
noise_level = 1 - noise / l_var
414419
415420
We can turn these warnings in exception, which enables us to do
416421
post-mortem debugging on them, and find our problem more quickly:
417422

418-
.. ipython::
419-
:verbatim:
420-
:okexcept:
423+
.. code-block:: ipython
421424
422425
In [3]: np.seterr(all='raise')
423-
Out[3]: {'divide': 'print', 'invalid': 'print', 'over': 'print', 'under': 'ignore'}
424-
In [4]: %run wiener_filtering.py
426+
Out[3]: {'divide': 'warn', 'over': 'warn', 'under': 'ignore', 'invalid': 'warn'}
427+
428+
In [4]: %run wiener_filtering.py
425429
---------------------------------------------------------------------------
426430
FloatingPointError Traceback (most recent call last)
427-
/home/esc/anaconda/lib/python2.7/site-packages/IPython/utils/py3compat.pyc in execfile(fname, *where)
428-
176 else:
429-
177 filename = fname
430-
--> 178 __builtin__.execfile(filename, *where)
431-
/home/esc/physique-cuso-python-2013/scientific-python-lectures/advanced/debugging/wiener_filtering.py in <module>()
432-
55 pl.matshow(noisy_face[cut], cmap=pl.cm.gray)
433-
56
434-
---> 57 denoised_face = iterated_wiener(noisy_face)
435-
58 pl.matshow(denoised_face[cut], cmap=pl.cm.gray)
436-
59
437-
/home/esc/physique-cuso-python-2013/scientific-python-lectures/advanced/debugging/wiener_filtering.py in iterated_wiener(noisy_img, size)
438-
38 res = noisy_img - denoised_img
439-
39 noise = (res**2).sum()/res.size
440-
---> 40 noise_level = (1 - noise/l_var )
441-
41 noise_level[noise_level<0] = 0
442-
42 denoised_img += noise_level*res
431+
File ~/src/scientific-python-lectures/advanced/debugging/wiener_filtering.py:52
432+
49 plt.matshow(face[cut], cmap=plt.cm.gray)
433+
50 plt.matshow(noisy_face[cut], cmap=plt.cm.gray)
434+
---> 52 denoised_face = iterated_wiener(noisy_face)
435+
53 plt.matshow(denoised_face[cut], cmap=plt.cm.gray)
436+
55 plt.show()
437+
438+
File ~/src/scientific-python-lectures/advanced/debugging/wiener_filtering.py:35, in iterated_wiener(noisy_img, size)
439+
33 res = noisy_img - denoised_img
440+
34 noise = (res**2).sum() / res.size
441+
---> 35 noise_level = 1 - noise / l_var
442+
36 noise_level[noise_level < 0] = 0
443+
37 denoised_img = np.int64(noise_level * res)
444+
443445
FloatingPointError: divide by zero encountered in divide
444446
445447
@@ -521,20 +523,24 @@ Type ``h`` or ``help`` to access the interactive help:
521523

522524
Documented commands (type help <topic>):
523525
========================================
524-
EOF bt cont enable jump pdef r tbreak w
525-
a c continue exit l pdoc restart u whatis
526-
alias cl d h list pinfo return unalias where
527-
args clear debug help n pp run unt
528-
b commands disable ignore next q s until
529-
break condition down j p quit step up
526+
EOF commands enable ll pp s until
527+
a condition exceptions longlist psource skip_hidden up
528+
alias cont exit n q skip_predicates w
529+
args context h next quit source whatis
530+
b continue help p r step where
531+
break d ignore pdef restart tbreak
532+
bt debug j pdoc return u
533+
c disable jump pfile retval unalias
534+
cl display l pinfo run undisplay
535+
clear down list pinfo2 rv unt
530536

531537
Miscellaneous help topics:
532538
==========================
533539
exec pdb
534540

535541
Undocumented commands:
536542
======================
537-
retval rv
543+
interact
538544

539545
Debugging segmentation faults using gdb
540546
==========================================

advanced/debugging/segfault.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
def make_big_array(small_array):
1010
big_array = stride_tricks.as_strided(
11-
small_array, shape=(2e6, 2e6), strides=(32, 32)
11+
small_array, shape=(int(2e6), int(2e6)), strides=(32, 32)
1212
)
1313
return big_array
1414

advanced/debugging/wiener_filtering.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,14 @@ def local_mean(img, size=3):
99
"""Compute a image of the local average"""
1010
structure_element = np.ones((size, size), dtype=img.dtype)
1111
l_mean = sp.signal.correlate(img, structure_element, mode="same")
12-
l_mean /= size**2
13-
return l_mean
12+
return np.int64(l_mean / size**2)
1413

1514

1615
def local_var(img, size=3):
1716
"""Compute a image of the local variance"""
1817
structure_element = np.ones((size, size), dtype=img.dtype)
1918
l_var = sp.signal.correlate(img**2, structure_element, mode="same")
20-
l_var /= size**2
19+
l_var = np.int64(l_var / size**2)
2120
l_var -= local_mean(img, size=size) ** 2
2221
return l_var
2322

@@ -35,7 +34,7 @@ def iterated_wiener(noisy_img, size=3):
3534
noise = (res**2).sum() / res.size
3635
noise_level = 1 - noise / l_var
3736
noise_level[noise_level < 0] = 0
38-
denoised_img += noise_level * res
37+
denoised_img = np.int64(noise_level * res)
3938
return denoised_img
4039

4140

0 commit comments

Comments
 (0)