Using a while loop as a wait in python - python

I have done this in C/C++ before where I have a while loop that acts as a wait holding the program up until the condition is broken. In Python I am trying to do the same with while(GPIO.input(24) != 0): and its says that it is expecting an indent. Is there anyway to get the script to hang on this statement until the condition is broken?

Do note that an empty while loop will tend to hog resources, so if you don't mind decreasing the time resolution, you can include a sleep statement:
while (GPIO.input(24) != 0):
time.sleep(0.1)
That uses less CPU cycles, while still checking the condition with reasonable frequency.

In Python, you need to use the pass statement whenever you want an empty block.
while (GPIO.input(24) != 0):
pass

Add a pass, as such:
while(GPIO.input(24) != 0):
pass
You might also consider a different approach:
while True:
if GPIO.input(24) == 0: break
Whichever you think is more readable.

In python you can't leave the colon : hanging so you must use a pass to complete the empty block. Another way to use a while in this way
while True:
if GPIO.input(24) == 0:
break

Related

Best way in python to check if a loop is not executed

The title might be misleading, so here is a better explanation.
Consider the following code:
def minimum_working_environment(r):
trial=np.arange(0,6)[::-1]
for i in range(len(trial)):
if r>trial[i]:
return i
return len(trial)
We see that if r is smaller than the smallest element of trial, the if clause inside the loop is never executed. Therefore, the function never returns anything in the loop and returns something in the last line. If the if clause inside the loop is executed, return terminates the code, so the last line is never executed.
I want to implement something similar, but without return, i.e.,
def minimum_working_environment(self,r):
self.trial=np.arange(0,6)[::-1]
for i in range(len(self.trial)):
if r>trial[i]:
self.some_aspect=i
break
self.some_aspect=len(self.trial)
Here, break disrupts the loop but the function is not terminated.
The solutions I can think of are:
Replace break with return 0 and not check the return value of the function.
Use a flag variable.
Expand the self.trial array with a very small negative number, like -1e99.
First method looks good, I will probably implement it if I don't get any answer. The second one is very boring. The third one is not just boring but also might cause performance problems.
My questions are:
Is there a reserved word like return that would work in the way that I want, i.e., terminate the function?
If not, what is the best solution to this?
Thanks!
You can check that a for loop did not run into a break with else, which seems to be what you're after.
import numpy as np
def minimum_working_environment(r):
trial = np.arange(0, 6)[::-1]
for i in range(len(trial)):
if r > trial[i]:
return i
return len(trial)
def alternative(r):
trial = np.arange(0, 6)[::-1]
for i in range(len(trial)):
if r > trial[i]:
break
else:
i = len(trial)
return i
print(minimum_working_environment(3))
print(minimum_working_environment(-3))
print(alternative(3))
print(alternative(-3))
Result:
3
6
3
6
This works because the loop controlling variable i will still have the last value it had in the loop after the break and the else will only be executed if the break never executes.
However, if you just want to terminate a function, you should use return. The example I provided is mainly useful if you do indeed need to know if a loop completed fully (i.e. without breaking) or if it terminated early. It works for your example, which I assume was exactly that, just an example.

Continuing function after else

thanks in advance for the help!
I'm building a simple program; the idea is for it to periodically check whether a variable has changed and, if it has, do something and, if not, check again. Use case: show a graph derived from the user's current URL in their browser; if the URL is unchanged, do nothing, if it changes, redraw the graph.
I'm running into an issue; I want my function to keep running while the condition is met, and if the condition is not met do something else, but then keep running.
Here's my while function code; my IDE and reading are telling me that "continue" is not permitted here: is there another way that I can keep my function active? Conversely, please do let me know if this is a foolish way to achieve what I'm trying to do!
while new_value != previous_value:
#wait
#do something
#put contents of new_value into previous_value
#update new_value from external source (e.g. URL from browser, which may or not be have changed)
else:
#wait
#do nothing
#put contents of new_value into previous_value
#update new_value from external source
continue
that's an alright start. The while loop will stop if the values are identical which is often. Inside the while loop you can add an if statement for the desired result. While True keeps going until stopped.
while True:
#wait for a couple of seconds
if new_value != previous_value:
#do something
#put contents of new_value into previous_value
#update new_value from external source
I would try something like this:
while True:
#wait some seconds if you need
if(new_value != previous_value):
#do something
else:
#update new_value from external source
I would use a while loop to keep your program running, and then use an if/else statement within the loop. Then just use break statement to stop running the loop.
while True:
if new_value != previous_value:
# Run your code
else:
# Run your code
# When I want the loop to end
break
The issue here is that the 'else' statement, when used like this, is being executed once your loop is already broken. As such there is nothing to 'continue' and your IDE is flagging a syntax error.
This is a somewhat obscure Python construct, but it (and the reasoning behind it) are well explained here at 15m53s.
What you're probably meaning to do is this:
while True:
if new_value != previous_value:
# Do one thing
else:
# Do a different thing
# You will need to specify an end condition,
# or it will continue looping indefinitely.
if exit_conditon_met:
break

Is there a conditional that runs if an if statement does not activate within a loop?

Making a simple program that swaps the location of numbers in a loop until they are in ascending order. I want the program to end when the if conditional is never activated within a instance of the for loop. Is there a shorter way to do this without the use of a while true/false or like?
while tf == True:
for i in range(lisLen-1):
tf=False
if listy[i]>listy[i+1]:
tf=True
swap(listy, i, i+1)
Get rid of the variable, and use break instead. Then you can use the else: clause to test this. That clause runs if the loop ended normally instead of with break.
while True:
for i in range(lisLen-1):
if listy[i]>listy[i+1]:
swap(listy, i, i+1)
break
else:
break

sys.exit(): is there a less extreme alternative?

I was hoping to get some kind of advice regarding the use of sys.exit(). I have used sys.exit() to stop a script from running any further:
My code:
if x != 20:
query = raw_input("X does not equal 20. Do you want to continue? (Y/N)")
if query in ['y', 'Y']:
pass
else:
sys.exit()
I have done some searching (and am still searching) but I was hoping to gain some clarity regarding the best practices use of sys.exit(). Is there something a little less extreme than killing the script? I'm considering the combination of extra loop and a more inquisitive question.
Since this is used at the beginning of your script (as mentioned by you). Use the coding pattern written below. And use return instead of sys.exit (actually since you are exiting from the script itself thereby terminating the process altogether sys.exit is not a bad practice).
Whether you use return or sys.exit return appropriate integer. its a good practice.
def do_something():
//process something
return 1
if __name__ == '__main__':
query = raw_input("Do you want to continue? (Y/N)")
if query.lower() == 'y':
//do something
do_something()
else:
print 'ERROR: Cant Understand Input. It has to be (Y/N). Exiting...'
return 0
Place your code in the main() function:
def main():
// your code
if __name__ == '__main__':
main()
Then you can exit from your script just by return
As other commenters have noted, a function provides you the option of using return to bail out from anywhere in the script and that's probably the best choice - I just thought I'd mention one piece of trivia:
Technically sys.exit raises a SystemExit exception. You can catch a SystemExit with an ordinary try-catch, effectively 'canceling' the exit if you want to. This might come in handy if you have more complex code in which a low level function might not have enough context to make a good decision but higher level code may want to step in and clean up.
People from C/C++ and lots of other languages get hives from this tactic but it's not uncommon in Pythonland. It's not a good idea to use exceptions for flow control in general but if you are using other people's functions, or combining smaller scripts into a larger application, it may be useful.
Don't forget, btw, that if control falls through to the bottom of your script it will just return 'None' anyway, so in your example:
if x != 20:
query = raw_input("X does not equal 20. Do you want to continue? (Y/N)")
if query in ['y', 'Y']:
// do something
is the same as
if x != 20:
query = raw_input("X does not equal 20. Do you want to continue? (Y/N)")
if query in ['y', 'Y']:
// do something
else:
sys.exit()
EXCEPT for the fact that you could try/catch around the second but not the first... though I assume your example is snipped from a larger sample where return is the better escape route

What is the best way on Python to identify if a break occurred on the last element iteration due to a condition within?

I saw some similar questions to this but none seems to address this is specific question so I don't know if I am overlooking something since I am new to Python.
Here is the context for the question:
for i in range(10):
if something_happens(i):
break
if(something_happened_on_last_position()):
# do something
From my C background, if I had a for (i=0;i<10;i++) doing the same thing with a break, then the value of i would be 10, not 9 if the break didn't occur, and 9 if it occurred on the last element. That means the method something_happened_on_last_position() could use this fact to distinguish between both events. However what I noticed on python is that i will stop on 9 even after running a successful loop without breaks.
While make a distinction between both could be as simple as adding a variable there like a flag, I never liked such usage on C. So I was curious, is there another alternative to do this or am I missing something silly here?
Do notice that I can't just use range(11) because this would run something_happens(10). It is different on C on this since '10' would fail on the condition on the for loop and would never execute something_happens(10) (since we start from index 0 here the value is 10 on both Python and C).
I used the methods just to illustrate which code chunk I was interest, they are a set of other conditions that are irrelevant for explaining the problem.
Thank you!
It works the other way:
for i in range(10):
if something_happens(i):
break
else: # no break in any position
do whatever
This is precisely what the else clause is for on for loops:
for i in range(10):
if something_happens(i):
break
else:
# Never hit the break
The else clause is confusing to many, think of it as the else that goes with all those if's you executed in the loop. The else clause happens if the break never does. More about this: For/else

Categories