Constantly looking for user input in Python
Question: How would I write a Python program that would always be looking for user
input. I think I would want to have a variable equal to the input and then
something different would happen based on what that variable equaled. So if
the variable were "w" then it would execute a certain command and keep doing
that until it received another input like "d" Then something different would
happen but it wouldn't stop until you hit enter.


Answer: If you want to **constantly** look for an user input you'll need
[**multithreading**](http://docs.python.org/py3k/library/threading.html).

Example:

    
    
    import threading
    import queue
    
    def console(q):
        while 1:
            cmd = input('> ')
            q.put(cmd)
            if cmd == 'quit':
                break
    
    def action_foo():
        print('--> action foo')
    
    def action_bar():
        print('--> action bar')
    
    def invalid_input():
        print('---> Unknown command')
    
    def main():
        cmd_actions = {'foo': action_foo, 'bar': action_bar}
        cmd_queue = queue.Queue()
    
        dj = threading.Thread(target=console, args=(cmd_queue,))
        dj.start()
    
        while 1:
            cmd = cmd_queue.get()
            if cmd == 'quit':
                break
            action = cmd_actions.get(cmd, invalid_input)
            action()
    
    main()
    

As you'll see this, will get your messages a little mixed up, something like:

    
    
    > foo
    > --> action foo
    bar
    > --> action bar
    cat
    > --> Unknown command
    quit
    

That's beacuse there are two threads writing to stdoutput at the same time. To
sync them there's going to be need of
[`lock`](http://docs.python.org/py3k/library/threading.html#lock-objects):

    
    
    import threading
    import queue
    
    def console(q, lock):
        while 1:
            input()   # Afther pressing Enter you'll be in "input mode"
            with lock:
                cmd = input('> ')
    
            q.put(cmd)
            if cmd == 'quit':
                break
    
    def action_foo(lock):
        with lock:
            print('--> action foo')
        # other actions
    
    def action_bar(lock):
        with lock:
            print('--> action bar')
    
    def invalid_input(lock):
        with lock:
            print('--> Unknown command')
    
    def main():
        cmd_actions = {'foo': action_foo, 'bar': action_bar}
        cmd_queue = queue.Queue()
        stdout_lock = threading.Lock()
    
        dj = threading.Thread(target=console, args=(cmd_queue, stdout_lock))
        dj.start()
    
        while 1:
            cmd = cmd_queue.get()
            if cmd == 'quit':
                break
            action = cmd_actions.get(cmd, invalid_input)
            action(stdout_lock)
    
    main()
    

Ok, now it's better:

    
    
        # press Enter
    > foo
    --> action foo
        # press Enter
    > bar
    --> action bar
        # press Enter
    > cat
    --> Unknown command
        # press Enter
    > quit
    

Notice that you'll need to press `Enter` before typing a command to enter in
"input mode".

