Continuing function after else - python

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

Related

Passing variables between functions in Python, then back to menu

Slowly progressing with my learning with Python and would love a little hand with some code I've tried to create.
I previously had this program running with Global Variables to get a proof of concept to learn about passing variables between functions. Fully worked fine. However, rather than running the function and returning to the menu, it will just stop where I return the value and not progress back to the main menu I created. It is at the point of "return AirportDetailsGlobal".
I'm sure its a simple one, and as said - still learning!
Really appreciate any help on this!
Full code is on pastebin for further reference - pastebin 89VqfwFV
print("\nEnter airport code for overseas")
osCode = input()
airports = airData
for line in airports:
if osCode in line:
print (osCode, "Found\n\n")
print("Airport Name:",line[1])
OverseaCodeGlobal = osCode
x = int(line[2])
AirDataGlobal = x #changed here
return AirportDetailsGlobal
break
else:
print('Incorrect Choice')
menu()
menu()
If you do a return then your code goes back to where it was called from. If it wasn't called from anywhere (ie. you just ran that script directly) then calling return is in most ways equivalent to calling sys.exit(), ie. the program terminates. It'll never hit your break, leave the loop, or hit your call to menu().
Also, your indentation as given there isn't right, the else is at the same level as the for, not the if. I don't think that's the problem but you might hit it next. ;-)

Python: how to envisage the interruption of a loop before its normal end

I have a loop running for quite a long time (several hours). It may be that the user, looking at the current results, considers the run iterations as sufficient and then wants to stop the loop before its natural end, but without interrupting the whole program (no "Ctrl+C") since some final results processing is necessary.
To do that, I added the possibility of creating a specific 'stop' file in the working directory. At each loop, the code verify if that file exists and, if that is the case, it end the loop. I do not know if this solution is efficient and whether better solutions exist.
Example
i = 0
while i < 1000 and not(path.isfile(path.join(self.wrkdir,'stop'))) :
DoSomeStuff
i += 1
FinalizingStuff
If the only reason for not using Ctrl+C is that you think it will stop all your program, then the best solution is to use it instead of watching the files.
Simply because you can catch this exception (it is called KeyboardInterrupt) in your code as any other and do whatever you want.
import time
try:
while True:
time.sleep(0.1)
except KeyboardInterrupt:
print('Ok, user is pissed with our loop, go further')
finally:
# if some resources need to be cleaned
pass
print('Here we are, nothing is lost')

How to stop code execution of for loop from try/except in a Pythonic way?

I've got some Python code as follows:
for emailCredentials in emailCredentialsList:
try:
if not emailCredentials.valid:
emailCredentials.refresh()
except EmailCredentialRefreshError as e:
emailCredentials.active = False
emailCredentials.save()
# HERE I WANT TO STOP THIS ITERATION OF THE FOR LOOP
# SO THAT THE CODE BELOW THIS DOESN'T RUN ANYMORE. BUT HOW?
# a lot more code here that scrapes the email box for interesting information
And as I already commented in the code, if the EmailCredentialRefreshError is thrown I want this iteration of the for loop to stop and move to the next item in the emailCredentialsList. I can't use a break because that would stop the whole loop and it wouldn't cover the other items in the loop. I can of course wrap all the code in the try/except, but I would like to keep them close together so that the code remains readable.
What is the most Pythonic way of solving this?
Try using the continue statement. This continues to the next iteration of the loop.
for emailCredentials in emailCredentialsList:
try:
if not emailCredentials.valid:
emailCredentials.refresh()
except EmailCredentialRefreshError as e:
emailCredentials.active = False
emailCredentials.save()
continue
<more code>

Using a while loop as a wait in 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

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