Alex Ermolaev
Alex Ermolaev

Reputation: 311

How to constantly wait for user input while printing values in a script?

I have a python script with some values, which are printed on the terminal for every second. But my script should be always waiting for users input and depend on input change the variables in the script.

Now I have the following code for just printing value every second. I want this script to constantly wait for user input in the background and depends on input change the value of floor.

import argparse
import sys
import time

def createParser ():
    parser = argparse.ArgumentParser()
    parser.add_argument ('-floor', '--floor')

    return parser

parser = createParser()
namespace = parser.parse_args(sys.argv[1:])

def main():
  floor = namespace.floor
  while True:
    print(floor)
    time.sleep(1)
main()

Upvotes: 0

Views: 1289

Answers (1)

bnaecker
bnaecker

Reputation: 6440

You don't need multithreading in this situation. You want to wait for input for up to one second, and then update the floor variable if anything was put in by the user. The best tool for something like this is the I/O multiplexing available in the select or selectors modules.

For example:

import sys
import select
floor = 0.0
timeout = 1.0
while True:
    rlist, wlist, xlist = select.select([sys.stdin], [], [], timeout)
    if len(rlist):
        floor = float(sys.stdin.readline().rstrip('\n'))
        print('New value received.')
    print(floor)

But I should point out that this is not a pleasant user experience. The values are constantly being printed, meaning that the user's input and the outputs are mixed together in the console. This doesn't affect how the program runs, since stdin and stdout are separate streams. It just makes it hard for the user to correctly input a value as the outputs are being printed simultaneously.

Are you sure that you need to constantly print? Might it be more useful to just wait for the user to put in a value, and then print that when it's received? In this case, you don't even need the select module, just wait for input with sys.stdin.readline().

Upvotes: 1

Related Questions