Debugging "in the middle of a huge loop" (python/pycharm) [duplicate] - python

I have a breakpoint in my Python debugger. I am using PyCharm. I want to iterate lets say 100 times to reach the point where I want to debug.
Now I can press 100 x times Resume Program, but is there a way to just execute a command to run n times over the breakpoint.

You can use a function in a conditional breakpoint to count iterations, take for example:
The conditional breakpoint can call a function which in addition to returning a boolean, counts the number of loop iterations.
def your_counter(stop):
global count
count = count + 1
if stop == count:
# count = 0 for periodic break
return True
else:
return False
The solution shown is for cases when a one-liner condition might not be practical, and/or when a loop counter needs to be implemented externally. Since the breakpoint condition is programmatic you can implement it to break periodically, or on any series/frequency criteria you want to apply.
The custom condition would break at the exact iteration you want, after you're done "step debugging" either press resume, stop, "run to cursor", or disable the breakpoint right-clicking on it (in practice this gets you out of the loop).
You can also change the value of any variable in the middle of debugging by editing in "variable watches".

PyCharm offers the possibility to add conditions on specific breakpoint.
This feature is called Conditional Breakpoints and you can find the documentation here.
I think that this is what you are looking for, because in this way you are able to enable the breakpoint only under specific conditions.

Related

Break out of loop from console while in debug mode

I'm debugging some code in PyCharm by stepping through line-by-line. The code involves a long for-loop, but for debugging purposes, I don't need to iterate through the whole thing. Instead, I'd like to break out after a few iterations. I'm trying to figure out how to do so without modifying my code to have special debugging instructions.
Example for loop
indices = range(10000, 0, -1)
for i, val in enumerate(indices):
print(val) # I can tell that it's working after a few iterations
The first thing I tried was typing break in the debugging console when paused at the print(val) line. This resulted in a syntax error
SyntaxError: 'break' outside loop
I also thought about using the debugging console line to modify the variable that I am enumerating over. For example, entering
indices = []
This has no effect on the iterator. Apparently, the iterator has an independent copy of the variable.
In another language, Java for example, I would take advantage of the termination condition, but python loops don't have a termination condition. I could rewrite my for-loop as a while-loop so that it would have an explicit termination condition, but that would obfuscate the code.
The other option would be to add special debugging instructions. For example,
mode = 'debug'
indices = range(10000, 0, -1)
for i, val in enumerate(indices):
print(val) # I can tell that it's working after a few iterations
if mode == 'debug' and i % 10:
break
I dislike doing this because inevitably, one of these special instructions gets left in after debugging is finished and mucks everything up.
Do I have any other options to break out of the loop from the debug console or without modifying the code?
I dislike doing this because inevitably, one of these special instructions gets left in after debugging is finished and mucks everything up.
Python for loops just aren't designed to be changed during execution, besides hard coding break, return or throwing StopIteration. (You are debugging, so either change the range in the loops expression list, or let it run through). The reason being the advantages of straightforward simplicity outweigh exposing the for loop counter - see PEP 212.

python How to while loop while true , run multiple functions together

def function():
while True:
...omission...(this function is repeated permanently)
i =0
while i < 4:
driver.execute_script("""window.open("URL")""")
driver.switch_to.window(driver.window_handles[-1])
time.sleep(1)
function()
time.sleep(1)
i += 1 #open new tab and run function.
it doesn't work because while true loop is repeated permanently. Is there any ways to run multiple functions together?
https://imgur.com/a/4SIVekS This picture shows what I want
According to your picture, what you want is to launch the function a set number of times (4?), and run those in parrallel.
On a single core, as is the normal behavior, straight up parallel processing is impossible. You need to access other cores and manage a decentralized processing. while is useless there. I'm worried the level of difficulty is over your current skills, but here we go.
The overall flow that you (probably, depends on the actual memory safety of your functions) need is:
- to create a thread pool with the set number of threads for the number of runs you want.
- indicate the function you need to run
- start them, making sure the start itself is non-blocking.
- ensure one functions's processing doesn't impact another's results. race conditions are a common problem.
- gather results, again, in a non-blocking way.
You can use several methods. I highly recommend you read up a lot on the following documentations.
Threading:
https://docs.python.org/3/library/threading.html
Multiprocessing:
https://docs.python.org/3/library/multiprocessing.html
I don't understand your question because I don't understand what your function is supposed to do.
while True:
will always create an infinite loop. "while" is a command that tells python to loop through the following block so long as the expression following it evaluates to True. True always evaluates to True.
It seems like you want to use a conditional, like you do in "while x < 4".
x < 4
...is an expression that evaluates to true when x is less than 4, and false if x is not less than 4. Everything below the line:
while x < 4:
will then run if x is less than 4, and when it's done running that code, it will go back and evaluate if x is less than 4 again, and if it is, run the code again. To include another while loop inside of that loop, that new loop also needs an expression to evaluate. If you want to evaluate the same expression, write it out:
while x < 4:
# do something
while x < 4:
#do more things
# do even more things
# change x at some point, or else you're in an infinite loop.
However, there's no reason to do that specifically, because you're already doing it. All of the code is only running when x < 4, so checking that condition again right there is redundant, and doing it in another loop doesn't make sense. If the inside loop is also incrementing x, then the outside loop won't loop and doesn't need to increment x.
Also, if you want a function to check a condition based on a variable outside the function, you'll want to pass things to that function.

how to use the display command of pdb python module?

display expression: prints out the value of an expression each time it gets changed. This is useful for monitoring the value of variables that get changed in loops. So, suppose the following is the code:
for i in range(100):
for j in range(100):
a=f(i,j)
I know something is wrong with the execution of a=f(i,j) for certain values of i and j. Then, how to use the display command from pdb module to find out the values of i and j when it does not work? I suppose when you use display command, it will display the value of i and j automatically, right? Do I need to combine the c command and b command from pdb module also? Many thanks for your time and attention.
display sets a "watch", so that each time execution stops (whether by completing a next, a step, or an until, or breaking on a continue ), if the value has changed, it will print a message showing the old value and the new value.
Since you know something is wrong with your f function, your easiest solution is to put a break on that function, and set display of the inputs inside that scope. Since you have shown us nothing about f, I don't know what the input variables will be called at that level, but it's likely that it won't be "i" and "j", so set the display appropriately.
I find display most useful for when I'm stepping through code that involves loops, using n or s or c. It keeps track of variables for me, and saves me from having to print the variables I'm interested in. If you know your problem is in f, you'll have to step through the code there yourself, and check all the variables at all the interesting statements. If you find yourself checking a variable repeatedly, that's where you use display.

Ignore pycharm breakpoint for first N hits

I'm trying to ignore a specific breakpoint in pycharm for the first N times it hits. Since I'm looking to set it to something like 10k, manually doing this is not an option. I found the expanded options for breakpoints, including the condition field, but I'm not sure how I can craft a condition which takes into account how many times the breakpoint has been hit. Thanks.
You can just create a variable in Python specifically for the breakpoint counting purpose, which you increment every time you you go past the break point line. Then just use that variable in your break point condition (i.e. breakpoint_count == 10000).
Update
If you can't add new code into the real python code you can use the breakpoint condition:
eval("exec('try:\\n x += 1\\nexcept NameError:\\n x = 1') or x == 10000")
What this does is execute a try statement which increments a variable or creates it if it doesn't exist. Then evaluates that along with a statement checking if the variable has been incremented enough times yet with that being your ending condition. Note, the exec is required to run the try, but the eval is needed to "return" the condition to PyCharm. This is absurdly hacky, but it works for your case!

ipdb debugger, step out of cycle

Is there a command to step out of cycles (say, for or while) while debugging on ipdb without having to use breakpoints out of them?
I use the until command to step out of list comprehensions, but don't know how could I do a similar thing, if possible, of entire loop blocks.
I believe this is the intent of the until command. It's like a next except that when a jump occurs to a previous line number for the loop, it will continue until exiting the loop.
unt(il)
Continue execution until the line with a number greater than the current
one is reached or until the current frame returns
In general, to "step out" of the current function, use return.
r(eturn)
Continue execution until the current function returns.
You can use j <line number> (jump) to go to another line.
for example, j 28 to go to line 28.
This could sound obvious: jump makes you jump.
This means that you don't execute the lines you jump: you should use this to skip code that you don’t want to run.
You probably need tbreak (Temporary breakpoint, which is removed automatically when it is first hit. The arguments are the same as break) as I did when I found this page.
If you are willing to use another debugger, trepan, has more ways you can step. It is more gdb-like. So you can give a count of how many times you want to step. Or you can give a line number in a continue debugger command which in essence sets a temporary breakpoint at the line and then issues "continue". Other things that change stepping are "set different". See also the even suffixes you can put on step.
Note that like ipdb, there is syntax highlighting of the source text.

Categories

Resources