<jupyter_start><jupyter_text>DebuggingOnce a program reaches a certain size, it is nearly impossible to get it right on the first try - even for the experienced programmers.It is not unsusual to spend more time fixing erros (called "bugs") in programs, than it took writing it in the first place.Some errors are easy to find, others are more elusive. Here we discuss strategies how to systematically narrow in on those bugs.  The example:The following function `mean()` doesn't seem to work. When we call it, the program seems to go on forever, without giving any results.  We need to interrupt the program: * when run as a .py script on the terminal with [Ctrl]+C * when run in a Jupyter notebook with "Kernel / Interrupt"<jupyter_code>def mean(nums):
    bot = len(nums)
    it = 0
    top = 0
    while it < len(nums):
        top += nums[it]
    return float(top) / float(bot)

a_list = [1, 2, 3, 4, 5, 6, 10, "one hundred"]
# Won't run!
#mean(a_list)<jupyter_output><empty_output><jupyter_text>Print StatementsA very simple way of debugging is adding `print` statements along the way, which will print some text or the content of a variable when the program reaches to that state.<jupyter_code>def mean(nums):
    bot = len(nums)
    it = 0
    top = 0
    print("Still Running at line 5")
    while it < len(nums):
        top += nums[it]
        print(top)
    return float(top) / float(bot)

a_list = [1, 2, 3, 4, 5, 6, 10, "one hundred"]
# Won't run!
#mean(a_list)<jupyter_output><empty_output><jupyter_text>This is a classical case of an infinite loop!  Do we need the `while` loop at all? Couldn't we just use the `sum()` function to add our numbers?Let's try:<jupyter_code>def mean(nums):
    top = sum(nums)
    bot = len(nums)
    return float(top) / float(bot)

a_list = [1, 2, 3, 4, 5, 6, 10, "one hundred"]
mean(a_list)<jupyter_output><empty_output><jupyter_text>Interactive DebuggingIntegrated Development Environments (or short IDE's) come with so called "interactive graphical debuggers" they are extremely useful when working on large projects.We will work with "Spyder" (Scientific PYthon Development EnviRonment), an open source IDE for Python. Spyder is part of the installer for this course. Some Python IDEs:* Spyder:  (Free, open-source)* PyCharm Community:  * PyDev     * Whic ca be installed as a plugin for [Eclipse](http://www.eclipse.org/),    * or as a part of LiClipse:  Download example files1. Download and unzip the following file and save them in the CMSC6950 folder on your Desktop:    *  Start Spyder Windows users:Open Spyder from the Start Menu. macOS and Linux users:1. Open a new Terminal with:    * on Linux:  [Shift]+[Ctrl]+T    * on macOS:  [Command]+T  or [Windows-key]+T at the lab computers.2. Then type `spyder` followed by [Enter] In Spyder (for everyone): Example 11. Click on the "File Explorer" tab (right half of the window in the middle)2. Navigate to **Desktop/CMSC6950**     You should see `debug_mean.py` and `debug_2.py` in the File Explorer.3. Open **`debug_mean.py`** by double clicking on the name in the File Exprorer.4. Double-click on the line number **14** in the left window, a red dot should appear next to the line number.     Alternatively: Place you cursor on line 14 and press the [F12] key (Set/Clear breakpoint).5. Click on the "**Debug File**" icon (>||) - or alternatively press [Ctrl]+[F5].6. Click repeatedly on the "**Run current line**" icon or press [Ctrl]+[F10].     Notice which line is highlited in the text editor.7. Click on the "**Variable Explorer**" tab (right half of the window in the middle).   Notice how the value of variable `top` keeps going up as we continue "Run current line".8. Click a few times on "**Continue** Execution **until next Breakpoint**" or press [Ctrl]+[F12].9. Click on "**Stop Debugging**" or press [Ctrl]+[Shift]+[F12]. Example 21. Open **`debug_2.py`** by double clicking on the name in the File Explorer.2. In this file **set a breakpoint** on **line 14** by double-clicking on the line numberor placing you cursor on line 14 and pressing the [F12] key.3. Click on the "**Debug File**" icon (>||) or press [Ctrl]+[F5].4. Click again on the "Variable Explorer" tab.5. Click on "**Continue** Execution **until next Breakpoint**" or press [Ctrl]+[F12].6. Click on "**Step into** function or method of current line" or press [Ctrl]+[F11].     Notice how the editor now shows the the `debug_mean.py` file again.7. Click repeatedly on "**Continue** Execution **until next Breakpoint**" or press [Ctrl]+[F12].8. Click on "**Stop Debugging**" or press [Ctrl]+[Shift]+[F12]. Example 31. Follow steps 1. and 2. from the previous example.2. Click on the tab "Python console" (bottom-right)3. Follow steps 3. to 7. 4. On the `(Pdb)` prompt (Python console) type: `nums[-1]=100`5. Notice that the list "nums" in the Variable explorer has changed.  Python's command line debugger (pdb)<jupyter_code>import pdb

# uncomment to run pdb
pdb.set_trace()
a_list = [1, 2, 3, 4, 5, 6, 10, "one hundred"]
mean(a_list)
a_list = [1, 2, 3, 4, 5, 6, 10, 100]
result = mean(a_list)
print(result)<jupyter_output>16.375
{'fraction_non_alphanumeric': 0.11056751467710371, 'fraction_numerical': 0.024853228962818004, 'mean_word_length': 4.209989806320081, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '315539', 'license': 'CC-BY-4.0', 'n_tokens_mistral': 1698, 'n_tokens_neox': 1564, 'n_words': 725, 'path': 'lectures/ch17-debugging.ipynb', 'repo_name': 'CMSC6950/CMSC6950.github.io', 'size': '5110'}