Keyboard input with timeout?
The example you have linked to is wrong and the exception is actually occuring when calling alarm handler instead of when read blocks. Better try this:
import signal
TIMEOUT = 5 # number of seconds your want for timeout
def interrupted(signum, frame):
"called when read times out"
print 'interrupted!'
signal.signal(signal.SIGALRM, interrupted)
def input():
try:
print 'You have 5 seconds to type in your stuff...'
foo = raw_input()
return foo
except:
# timeout
return
# set alarm
signal.alarm(TIMEOUT)
s = input()
# disable the alarm after success
signal.alarm(0)
print 'You typed', s
Keyboard input timeout with visible countdown
To do this you need to move with cursor in the terminal depending on the operating system you are using, it is very tiring and it is not very solid to use the terminal in that way (a static stdout would be easier and safer), what I would do it is an output of this kind obviously you have to use a multithread programming to be able to use the file descriptor simultaneously
import time
import sys
import threading
import time
import sys
def get_input(t):
global stop_threads
while True:
input_cmd = input().lower()
if input_cmd == "yes" or input_cmd == "yup":
print("\n\nThanks script is now starting\n\n")
break
elif input_cmd == "no" or input_cmd == "nope":
print("\nOk as you wish, I'm stopping...\n")
break
stop_threads = True
def initial_startup(t):
print('Do you want to continue?')
t1 = threading.Thread(target=get_input, args=(t,), daemon=True)
t1.start()
while t:
global stop_timeout
global stop_threads
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
prompt = "You have %s time left... Answer yes or no only: " % timer
print(prompt)
sys.stdout.write("\x1b[1A") # cursor up one line
sys.stdout.write("\x1b[2K") # delete the last line
if stop_threads:
sys.exit(1)
time.sleep(1)
t -= 1
if timer == "00:01":
sys.stdout.write("\x1b[2K") # delete the last line
print("Timeout! try again")
sys.exit(1)
stop_threads = False
stop_timeout = False
t = 4
initial_startup(int(t))
Output
Do you want to continue?
You have 00:02 time left... Answer yes or no only:
Ok as you wish, I'm stopping...
Do you want to continue?
You have 00:02 time left... Answer yes or no only:
Timeout! try again
Do you want to continue?
You have 00:05 time left... Answer yes or no only:
Thanks script is now starting
How to set a timeout for Input
Doing the task you proposed isn't as easy as you might've guessed. It is easier to use the signal
module to do this: (I have incorporated your code with a modified version of the answer I linked)
import signal, time
def TimedInput(prompt='', timeout=20, timeoutmsg = None):
def timeout_error(*_):
raise TimeoutError
signal.signal(signal.SIGALRM, timeout_error)
signal.alarm(timeout)
try:
answer = input(prompt)
signal.alarm(0)
return answer
except TimeoutError:
if timeoutmsg:
print(timeoutmsg)
signal.signal(signal.SIGALRM, signal.SIG_IGN)
return None
monsterhp = int(800)
y = 150
while monsterhp > 0:
timeout = 4
timeoutmsg = 'You ran out of time.'
print(" ")
prompt = "You have %d seconds Type 'attack' to hit the monster\nType here: " % timeout
answer = TimedInput(prompt, timeout, timeoutmsg)
if answer == "attack":
print("You strike the monster")
time.sleep(1)
monsterhp = monsterhp - y
print("War Lord Health:", monsterhp)
Note: this will only work on all unix/mac system
You can change your while loop to this, for a improved version of your code:)
while monsterhp > 0:
timeout = 4
timeoutmsg = 'You ran out of time.'
print(" ")
prompt = "You have %d seconds Type 'attack' to hit the monster\nType here: " % timeout
answer = TimedInput(prompt, timeout, timeoutmsg)
if answer == "attack":
print("You strike the monster")
time.sleep(1)
monsterhp = monsterhp - y
print("War Lord Health:", monsterhp)
elif answer == None:
print("The War Lord has killed you, you're now dead")
print("Thanks for playing, \nGAME OVER")
break
Skip the input function with timeout
You can use the inputimeout
module
You can install the module by running cmd and typing this command
pip install inputimeout
You can use it like this
from inputimeout import inputimeout, TimeoutOccurred
try:
var = inputimeout(prompt='>>', timeout=5)
except TimeoutOccurred:
var = ''
Steps to use
- Import the module in file
- start the try method
- make a variable and instead of input use
inputimeout
function and enter values as prompt=
andtimeout=
- In
except TimeoutOccurred:
enter the value of the var if timeout is occured
Time-Limited Input?
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: ")
python Keyboard input with timeout? getting error OSError: [WinError 10038] An operation was attempted on something that is not a socket
The solution I found is:
$ pip install inputimeout
from inputimeout import inputimeout, TimeoutOccurred
try:
something = inputimeout(prompt='>>', timeout=10)
except TimeoutOccurred:
something = 'Time is up'
print(something)
Timed user input in Python
You can use the Timer
class for this purpose
from threading import Timer
timeout = 10
t = Timer(timeout, print, ['Sorry, times up!'])
t.start()
prompt = "You have %d seconds to answer the question. What color do cherries have?...\n" % timeout
answer = input(prompt)
t.cancel()
Output:
You have 10 seconds to answer the question. What color do cherries have?
(After 10 seconds)
Sorry, times up!
Related Topics
Is There Go Up Line Character? (Opposite of \N)
Strip HTML from Strings in Python
How to Use Export With Python on Linux
Post Values from an HTML Form and Access Them in a Flask View
How to Unescape HTML Entities in a String in Python 3.1
Remove HTML Tags Not on an Allowed List from a Python String
What's the Easiest Way to Escape HTML in Python
How to Simulate Html5 Drag and Drop in Selenium Webdriver
How to Remove Script Tags With Beautifulsoup
Selenium.Common.Exceptions.Invalidselectorexception With "Span:Contains('String')"
How to Terminate a Python Subprocess Launched With Shell=True
Imagemagick Not Authorized to Convert Pdf to an Image
Unicodedecodeerror: 'Utf8' Codec Can't Decode Byte 0X9C
What Does ** (Double Star/Asterisk) and * (Star/Asterisk) Do For Parameters
Split a Pandas Column of Lists into Multiple Columns
Is False == 0 and True == 1 an Implementation Detail or Is It Guaranteed by the Language
Why Can a Function Modify Some Arguments as Perceived by the Caller, But Not Others