What are the differences between interactive debugging (python -m pdb foo.py) and hard-coded breakpoint (import pdb; pdb.set_trace()).
Most tutorials on dubuggers only focuse on the use of specific commands, but it would be interesting to understand:

What is the best practice in choosing debugging modes?
Do they have different performance in terms of computational time?
python -m pdb foo.py will pop you into the debugger at the very beginning of the program. This is likely to be useful in very small programs which you want to analyse as a whole.
In larger and more complex programs, where the situation you want to investigate arises after significant computiation at the top of a tall function call stack, this sort of usage is very impractical.
In such a case it is usually easier to set a hard breakpoint with import pdb; pdb.set_trace() at the point in your source code where the interesting situation arises. Then you launch the program normally, it executes normally, perhaps taking a significant time to perform many computations without your intervention, until it reaches the point you care about. Only when you reach the point of interest does the debugger ask you to intervene.
As for performance: In the first case, you will have to step through each and every statement in order advance; in the second, the debugger is not invoked until you reach the point of interest.
In the firt case, the CPU spends nearly all of its time waiting for the human to respond; in the second it spends most of its time on executing the program, until the point of interest is reached.
Python debugger: interactive debugging vs. hard-coded breakpoint