For Loop with Try Except Continuing Until End of Loop Range - python

I have written a for loop to retry a pyautogui.locateOnScreen statement until it finds the image. For some reason the code loops through all 20 cycles even though the image is found in the first few tries. Can anyone see the problem?
for x in range(0, 20):
try:
if pyautogui.locateOnScreen("PPTTTW.png", region=(537, 682, 93, 325)):
print("found")
str_error = None
except Exception as str_error:
pass
if str_error:
sleep(0.5)
else:
break

A simpler way to write this is to put the break statement directly in the try block, where it is only reached when an exception is not raised.
for _ in range(20):
try:
if pyautogui.locateOnScreen("PPTTTW.png", region=(537, 682, 93, 325)):
print("found")
break
except Exception as str_error:
logging.warning("Got %s, retrying...", str_error)
sleep(0.5)
else:
logging.error("Never found")

If you don't want the loop to continue after finding it, then use break in the corresponding if statement:
for x in range(0, 20):
try:
if pyautogui.locateOnScreen("PPTTTW.png", region=(537, 682, 93, 325)):
print("found")
str_error = None
break
except Exception as str_error:
pass
if str_error:
sleep(0.5)
else:
break
But are you sure you need a for loop even? Because I don't see you using x in there at all.

Related

Python if error in a loop continue loop from next iteration

I have such code:
for i in range(0,5):
try:
print(f"opened some_file_{i}")
except Exception as e:
print(f"error opening some_file_{i}")
return
print(f"i = {i}")
After exception, I need contuinue the loop from the next iteration, but not continue code (print(f"i = {i}")
How can I do it?
I tried to use a break, continue, pass statements and return
Sorry, continue works
for i in range(0,5):
try:
print(f"opened some_file_{i}")
except Exception as e:
print(f"error opening some_file_{i}")
continue
print(f"i = {i}")
So if I had an exception, continue will skip this loop iteration
If you have handled the exception properly it should continue on to the next iteration. You do not require break, continue, pass or return statements.
When you try to break or return the control will exit out of the loop/ function.
Example:
for i in range(0,5):
try:
print("Hello {}".format(i))
if i == 3:
raise Exception("Wrong file path error")
except Exception as e:
print(e)
Output

Continue executing a for loop is a specific system exit is raised in Python

I have a function that has multiple sys.exit() exceptions. I am calling the function iteratively and want my loop to continue if a certain sys.exit() is raised while error out for all others.
The sample code can be something like:
def exit_sample(test):
if test == 'continue':
sys.exit(0)
else:
sys.exit("exit")
list = ["continue", "exit", "last"]
for l in list:
try:
exit_sample(l)
except SystemExit:
print("Exception 0")
In the current form, the code will not error out but will print 'Exception 0' every time. I want it to not error out the first time, and then exit when l = "exit". How can that be done?
You can catch the exception, check if it is the one that justifies continue and re-raise it if it does not.
import sys
def exit_sample(test):
if test == 'continue':
sys.exit(0)
else:
sys.exit("exit")
lst = ["continue", "exit", "last"]
for l in lst:
try:
exit_sample(l)
except SystemExit as ex: # catch the exception to variable
if str(ex) == "0": # check if it is one that you want to continue with
print("Exception 0")
else: # if not re-raise the same exception.
raise ex
Store the exception in a variable and check if the code (or other characteristics) matches your condition for continuing your code. I modified your code such that it will continue if the exit code is 0 and otherwise re-raises system exit
import sys
def exit_sample(test):
if test == 'continue':
sys.exit(0)
else:
sys.exit("exit")
list = ["continue", "exit", "last"]
for l in list:
try:
exit_sample(l)
except SystemExit as exc:
if exc.code == 0:
print("continuing")
else:
# raise previous exception
raise
What you want is to convert the exception to a string and compare that with "exit". After seeing if it works, you can remove the print statement.
import sys
def exit_sample(test):
if test == 'continue':
sys.exit(0)
else:
sys.exit("exit")
list = ["continue", "exit", "last"]
for l in list:
try:
exit_sample(l)
except SystemExit as error:
print(error)
if str(error) == "exit":
sys.exit("foo")

Conditional except statements in Python

Is there a way to make an except statement conditional - in other words, only catch a type of exception if the condition is true? This is the idea I have, but it seems like it won't work
try:
<code>
if condition == True:
except Exception as e:
<error handling>
No, you can't do that. What you can do is catch the error then check the condition inside the except block and re-raise if necessary:
except Exception as e:
if not condition:
raise
Not like that, but I find this to be the cleanest solution
try:
<code>
except Exception as e:
if condition:
<error handling>
else:
raise # re raises the exception
You could use different exceptions for each case and catch them seperately:
import random
class myException_1(Exception):
pass
class myException_2(Exception):
pass
try:
a = random.randint(0,10)
if a % 2 == 0:
raise myException_1("something happened")
elif a % 3 ==0:
raise myException_2("something else happened")
else:
print("we made it!")
except myException_2 as e:
print("a was divisible by 3")
print(e)
except myException_1 as e:
print("a was divisible by 2")
print(e)

Exception Handling by validating simple inputs

I am new to Python, after I managed to learn Java at an advanced level.
In Java input validation with exception handling was never a problem to me but somehow in python i get a little confused:
Here an example of a simple FizzBuzz programm which can only read numbers in between 0 and 99, if otherwise, an exception has to be thrown:
if __name__ == '__main__':
def fizzbuzz(n):
try:
if(0<= n <= 99):
for i in range(n):
if i==0:
print("0")
elif (i%3==0 and i%7==0) :
print("fizzbuzz")
elif i%3==0:
print("fizz")
elif i%7==0:
print("buzz")
else:
print(i)
except Exception:
print("/// ATTENTION:The number you entered was not in between 0 and 99///")
try:
enteredNumber = int(input("Please enter a number in between 0 and 99: "))
fizzbuzz(enteredNumber)
except Exception:
print("/// ATTENTION: Something went wrong here. Next time, try to enter a valid Integer ////")
If i run that and enter e.g. 123 the code just terminates and nothing happens.
You need to raise an exception from fizzbuzz() when your condition is not met. Try below:
if __name__ == '__main__':
def fizzbuzz(n):
try:
if(0<= n <= 99):
for i in range(n):
if i==0:
print("0")
elif (i%3==0 and i%7==0) :
print("fizzbuzz")
elif i%3==0:
print("fizz")
elif i%7==0:
print("buzz")
else:
print(i)
else:
raise ValueError("Your exception message")
except Exception:
print("/// ATTENTION:The number you entered was not in between 0 and 99///")
try:
enteredNumber = int(input("Please enter a number in between 0 and 99: "))
fizzbuzz(enteredNumber)
except Exception:
print("/// ATTENTION: Something went wrong here. Next time, try to enter a valid Integer ////")
Also, you must catch specific exceptions instead of catching the generic exception.
If you want to catch an exception you need to make sure it will get raised if the desired scenario occurs.
Since the code block between try and except does not raise an exception by itself, you need to raise one by yourself:
try:
if(0<= n <= 99):
...
else:
raise Exception()
except Exception:
...

Python: Rerun try-except loop

I'm trying to rerun a try-except loop each time there is an error and only break when there is no error.
loop = True;
while loop == True:
try:
for i in data_names:
#do something
except Exception, e:
e = str(e)[0:100];
parse_error_list.append(str(e)[str(e).rindex(':')+2:str(e).rindex(':')+4]);
if len(e) == 0:
loop = False;
As a sanity check, will the following allow me to exit the loop if and only if there is no error?
EDIT: Is the answer? If so, is this the most efficient implementation? ...
loop = True;
while loop:
try:
for i in data_names:
#do something
except Exception, e:
e = str(e)[0:100];
parse_error_list.append(str(e)[str(e).rindex(':')+2:str(e).rindex(':')+4]);
if e:
loop = False;
The neatest solution would probably resemble:
while True:
try:
for i in data_names:
#do something
except Exception, e:
#log or otherwise handle exception
else:
break

Categories

Resources