4

I've been browsing a long time searching an answer to this.

I'm using Python 2.7 in Unix.

I have a continuous while loop and I need an option where user could interrupt it, do something and after that the loop would continue.

Like:

while 2 > 1:
     for items in hello:
         if "world" in items:
             print "hello"
         else:
             print "world"

      time.sleep(5)
      here user could interrupt the loop with pressing "u" etc. and modify elements inside he loop. 

I started testing out with raw_input, but since it prompts me out every cycle, it's something that I don't need.

I tried methods mentioned here:

Keyboard input with timeout in Python

couple of times, but none of those seem to work how I wish.

6
  • 1
    How do you wish it to work? I suppose that there's only one word for you then: threads. Commented Jul 31, 2013 at 14:08
  • 3
    Why would you use while 2>1 instead of while True? Commented Jul 31, 2013 at 14:10
  • raw_input() won't work fo reading one character, because "ordinary" console input is line buffered. See this recipe for unbuffered reading code.activestate.com/recipes/134892 Commented Jul 31, 2013 at 14:12
  • I use True in the original code. Thanks for mentioning threads. I will look into those. Commented Jul 31, 2013 at 14:13
  • 1
    What about the signal approach (discussed in the question you linked to) isn't working for you? It seems like it should be a workable solution... Otherwise, you can try using select (docs.python.org/release/2.5.2/lib/module-select.html) to poll the keyboard and see if it has any new input. Commented Jul 31, 2013 at 14:16

4 Answers 4

4
>>> try:
...    print 'Ctrl-C to end'
...    while(True):
...       pass
... except KeyboardInterrupt, e:
...    print 'Stopped'
...    raise
...
Ctrl-C to end
Stopped
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt
>>>

Obviously you need to replace pass with whatever you are doing and print with the aftermath.

Sign up to request clarification or add additional context in comments.

Comments

2

Here's how to do it by polling stdin:

import select, sys
p = select.poll()
p.register(sys.stdin, 1) #select the file descriptor, 
            #in this case stdin, which you want the 
            #poll object to pay attention to. The 1 is a bit-mask 
            #indicating that we only care about the POLLIN 
            #event, which indicates that input has occurred

while True:
     for items in hello:
         if "world" in items:
              print "hello"
         else:
              print "world"

     result = p.poll(5) #this handles the timeout too
     if len(result) > 0: #see if anything happened
         read_input = sys.stdin.read(1)
         while len(read_input) > 0:
              if read_input == "u":
                  #do stuff!
              read_input = sys.stdin.read(1) #keep going 
                            #until you've read all input

Note: This probably wouldn't work in Windows.

Comments

1

You could do nested while loops, something structured like this:

while true:
    go = True
    while go:
     for items in hello:
         if "u" in items:
             go = False
         else if "world" in items:
             print "hello"
         else:
             print "world"
    #Here you parse input to modify things in the nested loop, include a condition to set       
    #go back to true to reenter the loop                     

3 Comments

Python is a case-sensitive language. "true" and "false" are not defined. They should be "True" and "False".
This iterates through "hello" and searches "u" from there, which was not the problem.
I know what it does. I assumed hello was his list of input, though there wasn't much documentation. I though your problem was exiting a loop when a command is entered, and reentering it later, which this outlines (to the best of my ability, without understanding what any of your variables do) how to do.
0
import sys
import os
import time

import termios
import tty
import fcntl
import errno

KEY = "u"

def read_characters(f):
    fd = f.fileno()

    # put descriptor in non-blocking mode
    flags = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)

    try:
        while 1:
            try:
                yield f.read(1)
            except IOError as e:
                if e.errno == errno.EAGAIN:
                    # no more characters to read
                    # right now
                    break
    finally:
        # restore blocking mode
        fcntl.fcntl(fd, fcntl.F_SETFL, flags)

def main():
    fd = sys.stdin.fileno()

    # save current termios settings
    old_settings = termios.tcgetattr(fd)

    # tty sets raw mode using termios module
    tty.setraw(fd)

    try:
        while True:
            time.sleep(1)

            for c in read_characters(sys.stdin):
                if c == KEY: break
            else:
                c = None

            if c == KEY: break

            sys.stdout.write("still going\r\n")

    finally:
        # restore terminal settings
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

if __name__ == "__main__":
    main()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.