(Spyder maintainer here) There is a trick not many people know to introduce breakpoints wherever you want in your Python code: import pdb; pdb.set_trace().

In your case, you need to replace your code with

def foo():
    names = ['A', 'B', 'C']
    values = [11,12,13]
    i = 0
    import pdb; pdb.set_trace()
    for n in names:
        variable = str(n)  + ' = ' + str(values[i])
        print(variable)
        i += 1

foo()

and then run your file with Run file/F5 or also as a cell with Ctrl + Enter. With this simple change you'll get a debugger session exactly at the line pdb.set_trace() is placed and enter the for cycle below it to iterate line by line through it.

Note: Since Python 3.7 this is even simpler because it adds a new builtin function called breakpoint to replace pdb.set_trace(), but with the exact same effect.

Answer from Carlos Cordoba on Stack Overflow
🌐
Python
docs.python.org › 3 › library › pdb.html
pdb — The Python Debugger
List source code for the current file. Without arguments, list 11 lines around the current line or continue the previous listing. With . as argument, list 11 lines around the current line. With one argument, list 11 lines around at that line. With two arguments, list the given range; if the second argument is less than the first, it is interpreted as a count. The current line in the current frame is indicated by ->. If an exception is being debugged, the line where the exception was originally raised or propagated is indicated by >>, if it differs from the current line.
Top answer
1 of 2
9

(Spyder maintainer here) There is a trick not many people know to introduce breakpoints wherever you want in your Python code: import pdb; pdb.set_trace().

In your case, you need to replace your code with

def foo():
    names = ['A', 'B', 'C']
    values = [11,12,13]
    i = 0
    import pdb; pdb.set_trace()
    for n in names:
        variable = str(n)  + ' = ' + str(values[i])
        print(variable)
        i += 1

foo()

and then run your file with Run file/F5 or also as a cell with Ctrl + Enter. With this simple change you'll get a debugger session exactly at the line pdb.set_trace() is placed and enter the for cycle below it to iterate line by line through it.

Note: Since Python 3.7 this is even simpler because it adds a new builtin function called breakpoint to replace pdb.set_trace(), but with the exact same effect.

2 of 2
2

Visual Studio Community Edition

(with some Add-Ins not relevat to python):

Disclaimer: I use it because im familiar with it (C#) and it is free to use - not because it's especially pythonic.


Coding (Layout configureable):

  • Left: Code

  • Left-low: Output (normally I collaps that down to tabs only at the bottom to get more coding screen estate. Maybe downsized and switched to tab Error List which lists errors in your code (doh). Your code was perfect, so you do not see any of the sqigglies pointing out errors in the code.

  • Right: Solution explorer - essentially what files are inside this special python solution.

  • Right-low: Properties of a selected file

All the windows can be removed, resized, un-pinned to become "free floating windows" or collapsed into vertical tabs at left/right side of the window to get more screen estate for whats important to you)

See the red dots on the side of the lines? You place them before running the code. They mark break points, code execution automatically stops running when hitting one (basic use) or you can configure them to

  • not stop running but print out trace info of variables
  • stop only conditionally on f.e. variable value becomes 5 (loop index after that your program crashes all the time or other "conditions")
  • they can also only stop on 4th time hit and some other things:


Debugging Code:

F5 to start code running changes the layout (see above, you can change it and changes persist for next run):

When stopped you can hover over variables that are already used and inspect them, you can pin those information to the side - if one changes the text of the pin will get red to visualize this.

You can also put stuff in the "watch window" or use "quick watch" to inspect it - window lower half of screenshot. From a break you can continue wiht F5 to run till next breakpoint, or use F10 or F11:

  • F10 "steps over" statements line by line
  • F11 "steps into" statements - i.e. if your statement is function call it would execute the function wiht F10 and step into the function with F11

If inside a function you can use SHIFT+F11 complete the function and step out again and go from there.

I used F5 and F10 twice and I am currently at the line indicated by the arrow-thingy. You can also dragg the arrow some lines up to reexecute code, but this can have sideeffects - I rarly use it, most times I just restart the program Ctrl+Shift+F5 or stop debugging Shift+F5

The print output of your program is shown in a normal Console window thats cropped from the screenshots.

AddOn1: You can also simply execute all code, no debugging with CTRL+F5 and the IDE has 'a few' other features for python.

AddOn2: VS naturally comes with a lot of other features useful in an IDE, like integration to git etc. - if you use those they are "usable" from within the IDE via plugins -although some things are better done on the git.bash.

🌐
Brown University
cs.brown.edu › courses › csci0111 › fall2019 › lectures › python-debugging.html
Python: debugging, more loops
What are the pros and cons of print statements vs. the step-through debugger? Let’s say we want to write a function that takes a list of strings and counts the total number of “z”’s that appear. How could we do this? def zs_in_list(lst: list) -> int: count = 0 for s in lst: print(s) for c in s: print(c) if c == 'z': count = count + 1 return count
🌐
Invent with Python
inventwithpython.com › invent4thed › chapter6.html
Chapter 6 - Using the Debugger
It can be hard to figure out the source of a bug because the lines of code are executed quickly and the values in variables change so often. A debugger is a program that lets you step through your code one line at a time in the same order that Python executes each ...
🌐
Microsoft Learn
learn.microsoft.com › en-us › visualstudio › python › tutorial-working-with-python-in-visual-studio-step-04-debugging
Tutorial Step 4: Use Visual Studio Debugger - Python
In earlier versions of Visual Studio, you can close the output window automatically when the program completes. Select Tools > Options, expand the Python> Debugging node, and clear the Wait for input when process exits normally option.
🌐
Medium
medium.com › @sourleangchhean › how-to-use-the-python-debugger-43a05a826f82
How To Use the Python Debugger. Introduction | by Sour LeangChhean | Medium
May 2, 2017 - Next, we use the jump command to skip to line 6. At this point, the variable letter is set equal to the string 'a', but we jump the code that adds that to the list sammy_list. We then disable the breakpoint to proceed with the execution as usual with the continue command, so 'a' is never appended to sammy_list. Next, we can quit this first session and restart the debugger to jump back within the program to re-run a statement that has already been executed. This time, we’ll run the first iteration of the for loop again in the debugger:
🌐
Manifoldapp
cuny.manifoldapp.org › read › how-to-code-in-python-3 › section › de2c97ad-81dc-4dce-aa86-d6e1eda48d32
How To Use the Python Debugger | How To Code in Python 3 | Manifold @CUNY
Next, we use the jump command to skip to line 6. At this point, the variable letter is set equal to the string 'a', but we jump the code that adds that to the list sammy_list. We then disable the breakpoint to proceed with the execution as usual with the continue command, so 'a' is never appended to sammy_list. Next, we can quit this first session and restart the debugger to jump back within the program to re-run a statement that has already been executed. This time, we’ll run the first iteration of the for loop again in the debugger:
🌐
Python
docs.python.org › 2 › faq › programming.html
Programming FAQ — Python 2.7.18 documentation
At the end of the loop, the value of x is 4, so all the functions now return 4**2, i.e. 16. You can also verify this by changing the value of x and see how the results of the lambdas change: ... In order to avoid this, you need to save the values in variables local to the lambdas, so that they don’t rely on the value of the global x: >>> squares = [] >>> for x in range(5): ...
Find elsewhere
🌐
Muzny
muzny.github.io › csci1200-notes › 06 › 4 › debugging_while_loops.html
Debugging While Loops
September 8, 2022 - # TODO: run this code! x = 0 while x > 5: print(x) x += 1 # start debugging this code by printing the value of x after the loop print(x) The fix: this is most often due to either the initial value of the tracker variable or the logical expression being incorrect. What is happening here is that the very first time x > 5 gets tested, it evaluates to False so the loop does not run at all. In this case, we would want to change the logical expression to x < 5. A question for you: what would happen if instead of changing the logical expression, we changed the initial value of x to a number 5 or greater as in the code snippet below?
🌐
Real Python
realpython.com › python-debugging-pdb
Python Debugging With Pdb – Real Python
May 19, 2023 - In this first example, we’ll look at using pdb in its simplest form: checking the value of a variable. Insert the following code at the location where you want to break into the debugger: ... When the line above is executed, Python stops and waits for you to tell it what to do next.
🌐
University of Toronto
cs.toronto.edu › ~david › pyta › debug
Loop, Recursion and Memory Tracing — PythonTA documentation
Print-based debugging for loops and recursion: This feature makes tracing easier by printing the state of each loop iteration or recursive function call in a nicely-formatted table using the tabulate library. Snapshot-based debugging for visualizing the memory diagram: This feature makes it easier to visualize the Python memory model by leveraging the MemoryViz library.
🌐
DigitalOcean
digitalocean.com › community › tutorials › how-to-use-the-python-debugger
How To Use the Python Debugger | DigitalOcean
August 20, 2021 - Let’s quit the current session with the exit command and then begin the debugger again: ... next 500 x y z 600 x y z 700 x y z --Return-- > /Users/sammy/looping.py(12)<module>()->None -> nested_loop() (Pdb) While going through your code, you may want to examine the value passed to a variable, which you can do with the pp command, which will pretty-print the value of the expression using the pprint module: ... Most commands in pdbhave shorter aliases. For step that short form is s, and for next it is n.
🌐
Real Python
realpython.com › python-debug-idle
Find & Fix Code Bugs in Python: Debug With IDLE – Real Python
May 5, 2023 - To fix the problem, you need to tell Python to concatenate the string word[i] + "_" to the existing value of new_word. Press Quit in the Debug window, but don’t close the window just yet. Open the editor window and change the line inside the for loop to the following: ... Save the new changes to the program and run it again. In the Debug window, press Go to execute the code up to the breakpoint. Note: If you closed the debugger ...
🌐
JetBrains
jetbrains.com › help › pycharm › part-1-debugging-python-code.html
Part 1. Debugging Python Code | PyCharm Documentation
Provide the value for a in the Debug Console. The debugger will stop at the breakpoint. While the (Step Over) button executes the program until the next line in the current method, the (Step Into) button lets you see how the current line is executed. Click the (Step Into) button, and you will see that after the line a = int(input("a: ")) the debugger goes into the file parse.py: If you want to concentrate on your own code, use the (Step Into My Code) button — thus you'll avoid stepping into library classes.
🌐
Python Module of the Week
pymotw.com › 2 › pdb
pdb – Interactive Debugger - Python Module of the Week
July 3, 2010 - Programs with a lot of looping or recursive calls to the same function are often easier to debug by “skipping ahead” in the execution, instead of watching every call or breakpoint. The ignore command tells the debugger to pass over a breakpoint without stopping. Each time processing encounteres the breakpoint, it decrements the ignore counter. When the counter is zero, the breakpoint is re-activated. $ python -m pdb pdb_break.py > .../pdb_break.py(7)<module>() -> def calc(i, n): (Pdb) break 17 Breakpoint 1 at .../pdb_break.py:17 (Pdb) continue i = 0 > .../pdb_break.py(17)f() -> j = calc(i, n) (Pdb) next j = 0 > .../pdb_break.py(15)f() -> for i in range(n): (Pdb) ignore 1 2 Will ignore next 2 crossings of breakpoint 1.