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')
Related
The program isn't printing what I want ("too slow") after the except with the KeyboardInterrupt, which should end the program and print the string, instead the program just ends. I tried messing around with it a bit but can't seem to figure it out. What should I do?
import os
import signal
import threading
from random import randint
def timed_input(interval, *args):
t = threading.Timer(interval, os.kill, args=(os.getpid(), signal.SIGINT))
t.start()
try:
return int(input(*args))
except:
pass
finally:
t.cancel()
while True:
want = randint(1,9)
try:
got = timed_input(5, f'type "{want}": ')
except KeyboardInterrupt:
print('too slow')
else:
if got != want:
print('You Lose.')
break
This is because your first function is removing the KeyboardInterrupt thus making the second try block useless.
To fix this add another except block for the first function so it is properly raised:
import os
import signal
import threading
from random import randint
def timed_input(interval, *args):
t = threading.Timer(interval, os.kill, args=(os.getpid(), signal.SIGINT))
t.start()
try:
return int(input(*args))
except KeyboardInterrupt:
raise
except ValueError:
pass
finally:
t.cancel()
while True:
want = randint(1,9)
try:
got = timed_input(5, f'type "{want}": ')
except KeyboardInterrupt:
print('too slow')
else:
if got != want:
print('You Lose.')
break
This question already has answers here:
Keyboard input with timeout?
(28 answers)
Closed 3 years ago.
What I would like to be able to do is ask a user a question using input. For example:
print('some scenario')
prompt = input("You have 10 seconds to choose the correct answer...\n")
and then if the time elapses print something like
print('Sorry, times up.')
Any help pointing me in the right direction would be greatly appreciated.
If it is acceptable to block the main thread when user haven't provided an answer:
from threading import Timer
timeout = 10
t = Timer(timeout, print, ['Sorry, times up'])
t.start()
prompt = "You have %d seconds to choose the correct answer...\n" % timeout
answer = input(prompt)
t.cancel()
Otherwise, you could use #Alex Martelli's answer (modified for Python 3) on Windows (not tested):
import msvcrt
import time
class TimeoutExpired(Exception):
pass
def input_with_timeout(prompt, timeout, timer=time.monotonic):
sys.stdout.write(prompt)
sys.stdout.flush()
endtime = timer() + timeout
result = []
while timer() < endtime:
if msvcrt.kbhit():
result.append(msvcrt.getwche()) #XXX can it block on multibyte characters?
if result[-1] == '\r':
return ''.join(result[:-1])
time.sleep(0.04) # just to yield to other processes/threads
raise TimeoutExpired
Usage:
try:
answer = input_with_timeout(prompt, 10)
except TimeoutExpired:
print('Sorry, times up')
else:
print('Got %r' % answer)
On Unix you could try:
import select
import sys
def input_with_timeout(prompt, timeout):
sys.stdout.write(prompt)
sys.stdout.flush()
ready, _, _ = select.select([sys.stdin], [],[], timeout)
if ready:
return sys.stdin.readline().rstrip('\n') # expect stdin to be line-buffered
raise TimeoutExpired
Or:
import signal
def alarm_handler(signum, frame):
raise TimeoutExpired
def input_with_timeout(prompt, timeout):
# set signal handler
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(timeout) # produce SIGALRM in `timeout` seconds
try:
return input(prompt)
finally:
signal.alarm(0) # cancel alarm
Interesting problem, this seems to work:
import time
from threading import Thread
answer = None
def check():
time.sleep(2)
if answer != None:
return
print("Too Slow")
Thread(target = check).start()
answer = input("Input something: ")
I am working on a small project involving servos on the Raspberry Pi.
I wanted the servos to run for x amount of time then stop. Was trying out my code and am currently getting Invalid syntax on "def sleeper" and have no idea why.
Also being new to Stackoverflow, I had some issues indenting the code, my apologies!
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7,GPIO.OUT)
try:
while True:
GPIO.output(7,1)
time.sleep(0.0015)
GPIO.output(7,0)
def sleeper():
while True:
num = input('How long to wait: ')
try:
num = float(num)
except ValueError:
print('Please enter in a number.\n')
continue
print('Before: %s' % time.ctime())
time.sleep(num)
print('After: %s\n' % time.ctime())
try:
sleeper()
except KeyboardInterrupt:
print('\n\nKeyboard exception received. Exiting.')
exit()
That's because you didn't wrote any except block for the first try ... except pair:
This may work as you want:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7,GPIO.OUT)
try:
while True:
GPIO.output(7,1)
time.sleep(0.0015)
GPIO.output(7,0)
except:
pass
def sleeper():
while True:
num = input('How long to wait: ')
try:
num = float(num)
except ValueError:
print('Please enter in a number.\n')
continue
print('Before: %s' % time.ctime())
time.sleep(num)
print('After: %s\n' % time.ctime())
try:
sleeper()
except KeyboardInterrupt:
print('\n\nKeyboard exception received. Exiting.')
exit()
Check indentations please.
I have 10 threads, the problem is when something wrong happens raising the exception, bye will be printed 10 times.
I just want to print it once, then terminate all the threads. Is there any solution for the problem?
from threading import Thread
def printmsg(msg,threadNumber):
while True:
try:
print 'this is your message %s -- Thread Number:%s'%(msg,threadNumber)
except:
exit('Bye')
for i in range(0,11):
Thread(target=printmsg,args=('Hello Wrold',str(i))).start()
You could set a flag in the threads. n the main loop, you could join() all threads successively in order to wait until they are gone and then print a message if the flag is set.
The flag could even be the value of the exception...
from threading import Thread, Lock
stop = False
lock = Lock()
def printmsg(msg, threadNumber):
global stop
while True:
try:
if threadNumber in [3, 5, 7, 9]: # Something wrong happens
raise NotImplementedError
lock.acquire()
if stop:
lock.release()
break
print 'This is your message %s -- Thread Number: %s' % (msg, threadNumber)
lock.release()
except NotImplementedError:
lock.acquire()
if not stop:
stop = True
print 'Bye'
lock.release()
break
for i in range(0,11):
Thread(target=printmsg, args=('Hello World', i)).start()
Try to join all the child threads by the main thread. And do your job in main thread.
#-*-coding:utf-8-*-
from threading import Thread
def printmsg(msg,threadNumber):
while True:
try:
print 'this is your message %s -- Thread Number:%s'%(msg,threadNumber)
raise
except:
break
if __name__ == '__main__':
threads = []
for i in range(0,11):
threads.append(Thread(target=printmsg,args=('Hello Wrold',str(i))))
for t in threads:
t.start()
for t in threads:
t.join()
exit('Bye')
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