Automatically restart program when error occur - python

The program is like this:
HEADER CODE
urllib2.initialization()
try:
while True:
urllib2.read(somebytes)
urllib2.read(somebytes)
urllib2.read(somebytes)
...
except Exception, e:
print e
FOOTER CODE
My question is when error occurs (timeout, connection reset by peer, etc), how to restart from urllib2.initialization() instead of existing main program and restarting from HEADER CODE again?

You could wrap your code in a "while not done" loop:
#!/usr/bin/env python
HEADER CODE
done=False
while not done:
try:
urllib2.initialization()
while True:
# I assume you have code to break out of this loop
urllib2.read(somebytes)
urllib2.read(somebytes)
urllib2.read(somebytes)
...
except Exception, e: # Try to be more specific about the execeptions
# you wish to catch here
print e
else:
# This block is only executed if the try-block executes without
# raising an exception
done=True
FOOTER CODE

How about just wrap it in another loop?
HEADER CODE
restart = True
while restart == True:
urllib2.initialization()
try:
while True:
restart = False
urllib2.read(somebytes)
urllib2.read(somebytes)
urllib2.read(somebytes)
...
except Exception, e:
restart = True
print e
FOOTER CODE

Simple way with attempts restrictions
HEADER CODE
attempts = 5
for attempt in xrange(attempts):
urllib2.initialization()
try:
while True:
urllib2.read(somebytes)
urllib2.read(somebytes)
urllib2.read(somebytes)
...
except Exception, e:
print e
else:
break
FOOTER CODE

Related

How to try-except block exit when try is working

The code I have works. The last for loop gets reached and choice.click() gets clicked on. The question I have is why the except block gets executed even though the:
if choice.text == call_resource:
choice.click()
break
piece of the code is reached and the choice.click() portion works?
def select_choice(driver, resource_tag):
try:
call_resource = None
access_data = common.retrieve_tag_access_data()
for row in access_data["access_data"]:
if str(row["id"]) == resource_tag:
call_resource = row["row_tag"]["name"]
break
if call_resource is None:
access_data = common.retrieve_fixture_access_data()
for row in access_data["access_data"]:
if str(row["id"]) == resource_tag:
call_resource = row["row_tag"]["name"]
break
menu = driver.find_element_by_css_selector("ul[role='listgrid']")
choices = menu.find_elements_by_css_selector("li[role='choices']")
for choice in choices:
if choice.text == call_resource:
choice.click()
break
except:
error(logger, "unable to select choice")
pass
Because the last for loop works, shouldn't it break entirely out of the function after choice.click() without executing the except: portion of the code?
The except: portion will run only if an Exception occurred inside the try block. You should change the except: line to something like except Exception as e: and print the variable e in some way so you can discover what the problem is.
choices = menu.find_elements_by_css_selector("li[role='choices']")
for choice in choices:
if choice.text == call_resource:
choice.click()
break
Could be replaced with since your only trying to click one element with a certain text why not just try to find it. If it errors out it will go to the exception you provided.
driver.find_element(By.XPATH,f"//li[#role='choices' and contains(text(),{call_resource})]").click()
Also use to find errors use the following.
except Exception as e:
print(str(e))

KeyboardInterrupt exeption handling with time.sleep

I am going to display current time every 2 seconds and exception handling.
If there is KeyboardInterrupt, message should display like print('Program is stopped').
But in my code, try/except isn`t working.So how can I print message like 'Stopped'?
from datetime import datetime
import time
def display_time():
time.sleep(2)
current_time = datetime.now()
print('Time: ', current_time.strftime("%X"))
try:
while True:
display_time()
except KeyboardInterrupt:
print('Stopped')
print('Program ends')
You should check if Ctrl-C is pressed inside the while loop and, if so break outside the loop:
while True:
try:
display_time()
except KeyboardInterrupt:
print("Stopped")
break
print('Program ends')

Python password alarm for five minutes

I have written this python program for a game:
print("CC ACTIVATED")
import lcddriver
import time
import subprocess
display = lcddriver.lcd()
try:
display.lcd_display_string("CC... ", 1)
time.sleep(2)
display.lcd_display_string("ONLINE", 2)
time.sleep(2)
display.lcd_clear()
except Exception:
print("SCREEN ERROR")
try:
display.lcd_display_string("SETUP A", 1)
display.lcd_display_string("PASSWORD? Y/N", 2)
except Exception:
print("SCREEN ERROR")
activate = input("")
if activate == 'y':
print("ACTIVATED")
try:
display.lcd_clear()
display.lcd_display_string("", 1)
time.sleep(2)
display.lcd_display_string("LOADING", 2)
time.sleep(2)
display.lcd_clear()
except Exception:
print("SCREEN ERROR")
else:
print("ABORT")
try:
display.lcd_clear()
display.lcd_display_string("", 1)
time.sleep(2)
display.lcd_display_string("ABORT", 2)
time.sleep(2)
display.lcd_clear()
subprocess.call(["sudo","halt"])
except Exception:
print("SCREEN ERROR")
subprocess.call(["sudo","halt"])
k = True
while k:
try:
display.lcd_clear()
display.lcd_display_string("ENTER PASWORD", 1)
display.lcd_display_string("----------------", 2)
except Exception:
print("SCREEN ERROR")
pasword = input("")
display.lcd_clear()
try:
display.lcd_clear()
display.lcd_display_string("YOU TYPED:", 1)
display.lcd_display_string(pasword, 2)
time.sleep(2)
display.lcd_display_string("CONFIRM? Y/N", 1)
except Exception:
print("SCREEN ERROR")
ok = input("")
if ok == 'y':
k = False
else:
display.lcd_clear()
try:
display.lcd_clear()
display.lcd_display_string("PASSWORD", 1)
display.lcd_display_string("SET", 2)
except Exception:
print("SCREEN ERROR")
time.sleep(2)
run = True
try:
display.lcd_clear()
display.lcd_display_string("STARTING ", 1)
display.lcd_display_string("GAME...", 2)
except Exception:
print("SCREEN ERROR")
time.sleep(2)
while run:
try:
display.lcd_clear()
display.lcd_display_string("ENTER PASSWORD ", 1)
display.lcd_display_string("TO DEACTIVATE", 2)
except Exception:
print("SCREEN ERROR")
pasword1 = input("")
if pasword1 == pasword:
try:
display.lcd_clear()
display.lcd_display_string("PASSWORD....", 1)
time.sleep(2)
display.lcd_display_string("ACCEPTED", 2)
time.sleep(2)
display.lcd_clear()
display.lcd_display_string("DEACTIVATED", 2)
subprocess.call(["sudo","halt"])
time.sleep(10)
except Exception:
print("SCREEN ERROR")
subprocess.call(["sudo","halt"])
else:
try:
display.lcd_clear()
display.lcd_display_string("PASSWORD....", 1)
time.sleep(2)
display.lcd_display_string("UNACCEPTED", 2)
time.sleep(2)
except Exception:
print("SCREEN ERROR")
It runs on a raspberry pi and works absolutely fine, but there is one thing I want to do that is a bit above my skill level. I need this program to give you three attempts to guess the password,then at the fourth attempt play an audio recording. Afterward it needs to respond to failed attempts with the audio recording for five minutes and then go back to the silent three chances. I know how to get it to do the audio recording, but I need help with the five minute part. Does anyone here know how to do this? Thanks.
To permit three password attempts, you will need a counter variable which will count up to three with each failed attempt.
Rather than just running while k == True, you want to check against both k == True and attempts <= 3. As far as waiting five minutes, you will want to create a timestamp of when the user last guessed.
from datetime import datetime
...
k = True
password_attempts = 0
while k and password_attempts < 4:
try:
display.lcd_clear()
display.lcd_display_string("ENTER PASWORD", 1)
display.lcd_display_string("----------------", 2)
except Exception:
print("SCREEN ERROR")
pasword = input("")
display.lcd_clear()
try:
display.lcd_clear()
display.lcd_display_string("YOU TYPED:", 1)
display.lcd_display_string(pasword, 2)
time.sleep(2)
display.lcd_display_string("CONFIRM? Y/N", 1)
except Exception:
print("SCREEN ERROR")
ok = input("")
if ok == "y":
k = False
else:
display.lcd_clear()
password_attempts += 1
if password_attempts == 4:
#Create a timestamp of last attempt
last_request = datetime.now()
current_request = datetime.now()
while((last_request - current_request).total_seconds() < 5 * 60):
#Code to play music
current_request = datetime.now()
Then it's up to you to re-route the player back to the point in the program where they try entering the passwords again.
But, the design choices you've made at the beginning of this project will really start to get in the way of what you want to do.
I suggest you consider a redesign of your program, in order to make working on it much easier and more pleasant.
One of the best parts of programming is code re-use; this is most easily understood with functions. In Python, you create a function with the syntax def function_name():
Then, when you want to run the code within that function, you simply call it by name: function_name().
What does this mean for your app?
You could wrap writing to the LCD in a method, so that you can avoid repeatedly typing out the same try:... except: block (by the way... when you write except Exception, you are catching ALL exceptions your program might throw. This is considered bad practice, because you may not want to do the same thing irrespective of what the exception was in the first place. Rather, try to find a specific exception you're trying to catch, and catch that one by name, specifically).
An example of rewriting the LCD printing:
def print_to_lcd(statements_to_print: [str]):
line_number = 1
try:
for statement in statements_to_print:
display.lcd_display_string(statement, line_number)
line_number += 1
except Exception:
print("SCREEN ERROR")
Then, you just produce a list of things for the LCD to print, and call the LCD function with them:
things_to_write = ["PASSWORD...", "UNACCEPTED"]
print_to_lcd(things_to_write)
The same can be said about how you check your password value, when you play the music, etc.
Any time you find yourself repeatedly re-writing the same information, take a moment and think if there's a way you can write it once, and just re-use it. It'll make your programs much easier to write, and much easier to use.
Particularly in this case, since you want to re-do the same thing after waiting for a period of time. Imagine, rather than having to write tons of if-statements, when the user enters the password wrong for the fourth time, you just write something like:
play_music_for_five_minutes()
prompt_for_password()
Let me know if there are any further questions I can answer!

Python: run "try" again after exception caught and worked out

Is there any way to enter try statement once again after catching the exception in the first try?
Now I'm using "while" and "if" statements and it is making the code messy.
Any ideas?
Will try to simplify it as possible, sorry that have no logic...
run = True
tryAgain = True
a=0
while run:
try:
2/a
except Exception:
if tryAgain:
tryAgain = False
a = 1
else:
run = False
You could try using a break statement in your try block:
while True:
try:
# try code
break # quit the loop if successful
except:
# error handling
Considering you are doing this in a while, then you can make use of continue to just continue back to the beginning of the while loop:
tryAgain = True
a=0
while True:
try:
2/a
break # if it worked then just break out of the loop
except Exception:
if tryAgain:
continue
else:
# whatever extra logic you nee to do here
I like using a for loop so that the trying and trying doesn't go on forever. Then the loop's else clause is a place to put the "I give up" code. Here is a general form that will support 'n' retries > 1:
a=0
num_tries = 5
for try_ in range(0,num_tries):
try:
2/a
except Exception:
print("failed, but we can try %d more time(s)" % (num_tries - try_ - 1))
if try_ == num_tries-2:
a = 1
else:
print("YESS!!! Success...")
break
else:
# if we got here, then never reached 'break' statement
print("tried and tried, but never succeeded")
prints:
failed, but we can try 4 more time(s)
failed, but we can try 3 more time(s)
failed, but we can try 2 more time(s)
failed, but we can try 1 more time(s)
YESS!!! Success...
I'm new to Python, so this may not be best practice. I returned to the try statement after triggering the exception by lumping everything into a single function, then recalling that function in the except statement.
def attempts():
while True:
try:
some code
break #breaks the loop when sucessful
except ValueError:
attempts() #recalls this function, starting back at the try statement
break
attempts()
Hope this addresses your question.

Repeat an iteration in loop if error occurs

Is there a command such as break and continue which could repeat recent iteration?
For example, when exception is thrown.
for i in range(0,500):
try:
conn = getConnection(url+str(i))
doSomething(conn)
except:
repeat
Let's have an iteration where i variable's value is 6. During this iteration some connection error occurred. I want to repeat this iteration.
Is there a command which can do that?
Of course I can do this:
i=0
while i!=500:
try:
conn = getConnection(url+str(i))
doSomething(conn)
i+=1
except:
pass
No, there is no command to "rewind" a for-loop in Python.
You could use a while True: loop inside the for-loop:
for i in range(500):
while True:
try:
conn = getConnection(url+str(i))
doSomething(conn)
except Exception: # Replace Exception with something more specific.
continue
else:
break
or without the else::
for i in range(500):
while True:
try:
conn = getConnection(url+str(i))
doSomething(conn)
break
except Exception: # Replace Exception with something more specific.
continue
But I personally think that your proposed solution is better because it avoids an indentation level.
for i in range(500):
while True
try:
conn = getConnection(url+str(i))
break
except Exception: # still allows to quit with KeyboardInterrupt
continue
do_your_stuff()
This looks bit risky, however, you should at least enable some logging inside a while block.
If you expect to use it in more places, you might write a simple decorator:
def keep_trying(fn, *args, **kwargs):
def inner(*args, **kwargs):
while True:
try:
return fn(*args, **kwargs)
except Exception:
continue
return inner
# later you can use it simple like this:
for i in range(500):
conn = keep_trying(getConnection)(url+str(i))
You can use generators :
def process_connections(n_connections, url, max_tries=50):
i = 0
try_count = 0
while i < n_connections:
try:
conn = getConnection(url+str(i))
yield conn
except:
try_count += 1
if try_count > max_tries:
raise Exception("Unable to connect after %s tries" % max_tries)
else:
i += 1 # increments only if no exception
And you perform your operations :
for conn in process_connections(500, url):
do_something(conn)
You can use nested for loops to put a cap on the number of times you retry the operation. This is bascially the sam as #PierreAlex's generator answer but without the extra function definition.
for i in range(500):
for retry in range(10):
try:
conn = getConnection(url+str(i))
doSomething(conn)
except Exception: # Replace Exception with something more specific.
time.sleep(1)
else:
print "iteration", i, "failed"
Why not just use an if statement?
n=6
i=0
while i!=500:
failed = False;
try:
conn = getConnection(url+str(i))
doSomething(conn)
i+=1
except:
#handle error
failed = True;
#try again if n-th case failed first time
if(i == n and failed):
try:
conn = getConnection(url+str(i))
doSomething(conn)
except:
#handle error
Here is one. You would need to add a logging or alert system to let you know that something is stuck:
state = "" #state of the loop
# If there is no error continue. If there is error, remain in loop
while True:
if state != "error":
try:
1/0 # command
break # no error so break out of loop
except:
state = "error" #declare error so maintain loop
continue
elif state == "error": # maintain loop
continue

Categories