python - User input with a timeout, in a loop -


i'm trying create looping python function performs task , prompts user response , if user not respond in given time sequence repeat.

this loosely based off question: how set time limit on raw_input

the task represented some_function(). timeout variable in seconds. have 2 problems following code:

  1. the raw_input prompt not timeout after specified time of 4 seconds regardless of whether user prompts or not.

  2. when raw_input of 'q' entered (without '' because know typed automatically entered string) function not exit loop.

`

import thread import threading time import sleep  def raw_input_with_timeout():     prompt = "hello me you're looking for?"     timeout = 4     astring = none     some_function()     timer = threading.timer(timeout, thread.interrupt_main)     try:         timer.start()         astring = raw_input(prompt)     except keyboardinterrupt:         pass     timer.cancel()     if astring.lower() != 'q':         raw_input_with_timeout()     else:         print "goodbye" 

`

warning: intended work in *nix , osx requested not work in windows.

i've used this modification of activestate recipe basis code below. it's easy-to-use object can read input timeout. uses polling collect characters 1 @ time , emulate behavior of raw_input() / input().

input timeout

note: apparently _getch_nix() method below doesn't work op me on osx 10.9.5. might have luck calling _getch_osx() instead although seems work in 32-bit python since carbon doesn't support 64-bit.

import sys import time   class timeoutinput(object):     def __init__(self, poll_period=0.05):         import sys, tty, termios  # apparently timing of import important if using ide         self.poll_period = poll_period      def _getch_nix(self):         import sys, tty, termios         select import select         fd = sys.stdin.fileno()         old_settings = termios.tcgetattr(fd)         try:             tty.setraw(sys.stdin.fileno())             [i, o, e] = select([sys.stdin.fileno()], [], [], self.poll_period)             if i:                 ch = sys.stdin.read(1)             else:                 ch = ''         finally:             termios.tcsetattr(fd, termios.tcsadrain, old_settings)         return ch      def _getch_osx(self):         # same discussion on original activestate recipe:         # http://code.activestate.com/recipes/134892-getch-like-unbuffered-character-reading-from-stdin/#c2         import carbon         if carbon.evt.eventavail(0x0008)[0] == 0:  # 0x0008 keydownmask             return ''         else:             # event contains following info:             # (what,msg,when,where,mod)=carbon.evt.getnextevent(0x0008)[1]             #             # message (msg) contains ascii char             # extracted 0x000000ff charcodemask;             # number converted ascii character chr() ,             # returned             (what,msg,when,where,mod)=carbon.evt.getnextevent(0x0008)[1]             return chr(msg & 0x000000ff)      def input(self, prompt=none, timeout=none,               extend_timeout_with_input=true, require_enter_to_confirm=true):         """timeout: float seconds or none (blocking)"""         prompt = prompt or ''         sys.stdout.write(prompt)  # avoids couple of problems printing         sys.stdout.flush()  # make sure prompt appears before start waiting input         input_chars = []         start_time = time.time()         received_enter = false         while (time.time() - start_time) < timeout:             # keep polling characters             c = self._getch_osx()  # self.poll_period determines spin speed             if c in ('\n', '\r'):                 received_enter = true                 break             elif c:                 input_chars.append(c)                 sys.stdout.write(c)                 sys.stdout.flush()                 if extend_timeout_with_input:                     start_time = time.time()         sys.stdout.write('\n')  # consistency other "prints"         sys.stdout.flush()         captured_string = ''.join(input_chars)         if require_enter_to_confirm:             return_string = captured_string if received_enter else ''         else:             return_string = captured_string         return return_string 

test it

# should work raw_input() except time out ti = timeoutinput(poll_period=0.05) s = ti.input(prompt='wait timeout:', timeout=5.0,              extend_timeout_with_input=false, require_enter_to_confirm=false) print(s) 

repeated input

this implements original intention understand it. don't see value making recursive calls - think want input repeatedly? please correct me if wrong.

ti = timeoutinput() prompt = "hello me you're looking for?" timeout = 4.0 while true:     # some_function()     s = ti.input(prompt, timeout)     if s.lower() == 'q':         print "goodbye"         break 

Comments

Popular posts from this blog

java - UnknownEntityTypeException: Unable to locate persister (Hibernate 5.0) -

python - ValueError: empty vocabulary; perhaps the documents only contain stop words -

ubuntu - collect2: fatal error: ld terminated with signal 9 [Killed] -