Reputation: 4035
My program is working with input() from user. I want to print "hey,are you there?"
when the user hasn't written anything in 5 seconds. For example, the user writes something, and stops typing. If the user waits more than 5 seconds, then I want to print "hey,are you there?"
. So far I tried this:
while True:
start=time.time()
x=input("enter something")
end=time.time()
dif=end-start
if 5<dif:
print("hey are you there?")
It didn't work as I expected, because it waits for the user. It's writing "hey are you there?"
after the user wrote something. But I expect that when the user doesn't type anything, it also means x==False
, I want to warn the user.
Update I tried this one:
import msvcrt
import time
time1 = 0
print('enter something: ')
while not msvcrt.kbhit():
time.sleep(1)
time1 +=1
if time1 == 5:
print("hey are you there?")
while msvcrt.kbhit():
x = input()
It didn't work either. It printed "hey are you there?"
after 5 seconds even x==True
. So far no solution, hope I explained what I need.
Upvotes: 2
Views: 368
Reputation: 54163
Having trouble getting msvcrt.kbhit
to register and don't have time to debug at the moment, so I can't detect a key press to reset the timer. I'll edit when I can figure it out but working on this over my breaks at work since it seems like an interesting problem!
import threading
import queue
import msvcrt
import time
class Listener(threading.Thread):
def __init__(self, msg, in_q):
super().__init__()
self.__in_q = in_q
self.msg = msg
def run(self):
last_time = time.time()
while True:
try:
self.__in_q.get_nowait()
except queue.Empty:
pass # no poison pill, continue
else:
return 0 # poison pill, so end
cur_time = time.time()
timedelta = cur_time - last_time
if timedelta >= 5:
last_time = cur_time
print(self.msg)
if msvcrt.kbhit():
last_time = cur_time
# THIS BLOCK IS NOT CURRENTLY WORKING
# POSSIBLY msvcrt.kbhit WILL NOT CAPTURE THIS PROMPT?
if __name__ == "__main__":
q = queue.Queue()
listener = Listener("Are you still there?", q)
listener.start()
response = input("enter something: ")
q.put("poison")
Using an implementation of input
that Fred S hacked in, I was able to get this working as intended. It feels like kludge (and it is) but that's the best I can do on the command line in Windows.
import threading
import queue
import msvcrt
import time
import sys
class Listener(threading.Thread):
def __init__(self, in_q, msg=""):
super().__init__()
self.__in_q = in_q
self.msg = msg
def run(self):
last_time = time.time()
while True:
cur_time = time.time()
try:
tmp = self.__in_q.get_nowait()
except queue.Empty:
pass # no message, OK
else:
# message exists. Is it a poison pill?
if tmp == "poison":
# poison pill, kill process
return
else:
last_time = time.time()
# not poison pill, so refresh the timer
timedelta = cur_time - last_time
if timedelta >= 5:
last_time = cur_time
print(self.msg)
def new_input(prompt="", out_q=None):
"""Uses msvcrt.getch to simulate Py3's input
allows you to pass a queue to receive each
character."""
result = ""
print(prompt, end="")
while True:
sys.stdout.flush()
ch = msvcrt.getch().decode()
sys.stdout.write(ch)
if out_q:
out_q.put(ch)
if "\r" in ch:
return result
else:
result += ch
if __name__ == "__main__":
q = queue.Queue()
listener = Listener(q, "Are you still there?")
listener.start()
result = new_input("enter something: ", q)
q.put("poison")
print("You entered " + result)
Upvotes: 1
Reputation: 995
Seems like this works, but I'm using python 2.7:
import threading, time
class ValueGetter(object):
def __init__(self, wait_time_sec = 5.0):
self.stop_flag = True
self.wait_time_sec = wait_time_sec
def get_value(self):
self.stop_flag = False
p = threading.Thread(target=self.print_uthere)
p.start()
retval = raw_input('enter something:\n')
self.stop_flag = True
p.join()
return retval
def print_uthere(self):
tprint = tnow = time.clock()
while not self.stop_flag:
if tnow > (tprint + self.wait_time_sec):
print 'Are you there???'
tprint = time.clock()
time.sleep(0.01)
tnow = time.clock()
v = ValueGetter()
print v.get_value()
Here is a modified version that will reset the 5 sec timer whenever they enter a key. Windows only though.
import threading, time, msvcrt, sys
class ValueGetter(object):
def __init__(self, wait_time_sec = 5.0):
self.stop_flag = True
self.wait_time_sec = wait_time_sec
self.tprint = self.tnow = time.clock()
def get_value(self):
self.stop_flag = False
p = threading.Thread(target=self.print_uthere)
p.start()
print 'enter something:'
retval = ''
ch = ''
while not ch == '\r':
retval += ch
ch = msvcrt.getch()
sys.stdout.write(ch)
self.tprint = time.clock()
print
self.stop_flag = True
p.join()
return retval
def print_uthere(self):
self.tprint = self.tnow = time.clock()
while not self.stop_flag:
if self.tnow > (self.tprint + self.wait_time_sec):
print 'Are you there???'
self.tprint = time.clock()
time.sleep(0.01)
self.tnow = time.clock()
v = ValueGetter()
print v.get_value()
Upvotes: 2