Matplotlib: Hang up on conditional plotting - python

The following code hangs,
while np.any((np.log10((O3 / HB)) < 0.61 / (np.log10(N2 / HA) - 0.05) + 1.3).any()):
plt.plot(np.array(np.log10(N2 / HA)), np.array(np.log10(O3 / HB)), '.g')
plt.plot(np.array(np.log10(N2 / HA)), np.array(np.log10(O3 / HB)), '.r')
The plot works without the "while" condition. In the above form it hangs.
Do I need a "break"?
thanks

The code probably freezes because you are making a new plot object every time the loop iterates, eventually you'll run out of memory. The program usually spits out a warning after 20 or so plots made.
You can clear the axis each time as an alternative, or
When to use cla(), clf() or close() for clearing a plot in matplotlib?
or you could use the .set_xdata, set_ydata commands to simply update the data. Or you could reuse the same axes if you want to overlay the data.

Discussion of Issue
The code freezes because you are using a while loop with a condition whose variables do not change within the loop. Therefore, if the condition evaluates to True the first time through the loop, it will evaluate to True indefinitely, (i.e. the code 'hangs'). Typically (unless you want the loop to run forever) one or more variables within a while loop will change within the loop. A very simple example is,
while index < 10:
plt.plot(x_data[index], y_data[index])
index += 1 # Here the index changes.
Note: For these purposes it is more common to use for index in range(10): or better yet for xd, yd in zip(x_data, y_data): plt.plot(xd, yd) rather than a while loop because then you don't need to have the index += 1 line, and it is clearer at the beginning of the loop what is going on. I merely provided this as a clear example use of while.
Even if the conditional variables do change within the loop (i.e. if you're only providing a snippet of your while loop), it is possible that the conditional statement always evaluates to True. In this case, again, you will never exit the while loop and your code will 'hang'.
Potential Solutions
There are several ways you could fix your problem depending on what you are trying to do:
If you just want to plot your data once, use if instead of while.
If you are only showing us a snippet of your loop and the variables in the conditional statement do change within the loop, I would recommend:
A) starting by placing a print(np.any((np.log10((O3 / HB)) < 0.61 / (np.log10(N2 / HA) - 0.05) + 1.3).any())) at the top of your loop and run your code. I presume this will dump True to your console.
B) You could then start to break this statement apart using more print statements such as print('N2: %f' % N2) to understand why your statement is never evaluating to False and therefore you are never exiting the loop.

Related

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

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.

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!

help!for function

I have post the similar question before,but this time the problem is different,I got stuck with the following code..can anyone help with it?thanks in advance
I have fixed mu code as suggested,thanks
from numpy import *
#vs,fs,rs are all m*n matrixs,got initial values in,i.e vs[0],fs[0],rs[0] are known
#want use this foor loop to update them
vs=zeros((10,3))
vs[0]=([1,2,3])
fs=zeros((10,3))
fs[0]=([2,3,4])
vs=zeros((10,3))
vs[0]=([3,4,5])
for i in range(5):
#start looping..
vs[i+1]=vs[i]+fs[i]
fs[i+1]=(rs[i]-re[i])
rs[i+1]=rs[i]+vs[i]
print vs,fs,rs
then this code gives vs,fs,rs in different i,but not update each rows of rs,fs,vs and return me a single array of rs,fs,vs (fully updated). whats the problem here?..what should I add?thanks
Put your inizialization outside the loop! Right now, you're resetting the arrays to all zeros each time through the loop, over and over, which is absurd. You also appear to have a typo -- you set vs twice and rs never -- so I've tried to guess what you meant.
from numpy import *
#vs,fs,rs are all m*n matrixs,got initial values in,i.e vs[0],fs[0],rs[0] are known
#want use this foor loop to update them
vs=zeros((10,3))
vs[0]=([1,2,3])
fs=zeros((10,3))
fs[0]=([2,3,4])
rs=zeros((10,3))
rs[0]=([3,4,5])
for i in range(5):
#start looping..
vs[i+1]=vs[i]+fs[i]
fs[i+1]=rs[i]-re[i]
rs[i+1]=rs[i]+vs[i]
print vs,fs,rs
You do not start looping where the comment indicates it, but at the for i in range(5): line. Everything in the indented block (the "body of the for-loop") is done repeatedly for each i. So setting vs and fs to zero is done repeatedly, each time deleting what was calculated before. These initializations should be done before the for.
Also vs is initialized twice while rs isn't initialized at all, probably that's a typo and it should look like this:
vs=zeros((10,3))
vs[0]=([1,2,3])
fs=zeros((10,3))
fs[0]=([2,3,4])
rs=zeros((10,3))
rs[0]=([3,4,5])
for i in range(5):
#start looping..
...
I don't know exactly what you want to print. If you want to print every matrix every time it is updated, then you're fine. But if you want to print the matrices after all the updates have been completed, then you should bring that print statement out of the for loop.
This and what Alex and sth have said should fix your code fully

Categories

Resources