2

I have two threads one logging out to the console information at a specific interval and one taking in user input from the same console both on an infinite while loop

from threading import Thread
import time

WHITE =  '\033[97m'    # User Input color
YELLOW = '\033[93m'    # Log output color
BLUE =   '\033[94m'    # Input prompt color
CYAN =   '\033[96m'    # Input result color

def logging():
    while True:
        # DO SOMETHING TO CREATE THE "Log text"
        print(YELLOW + "[{}] Log text".format(time.strftime('%X')) + WHITE)
        time.sleep(2)

def inputing():
    while True:
        userInput = input(BLUE + "Enter your input > " + WHITE)
        # DO SOMETHING WITH userInput
        print(CYAN + "Displaying result computed for input = '{}'".format(userInput) + WHITE)

logging_thread = (Thread(target=logging, args=( )))
logging_thread.start()

input_thread = (Thread(target=inputing, args=( )))
input_thread.start()

The output from the logging thread keeps on interrupting my user input like this : gif of my console

I have tried a modification of the above code using '\r' to go back to the beginning and then using '\033[K' to erase the line as a hack which is comparatively cleaner but this is leading to my user input also getting erased. Code is like this:

ERASE_LINE = '\r' + '\033[K'

def logging():
    while True:
        # DO SOMETHING TO CREATE THE "Log text"
        print(ERASE_LINE + YELLOW + "[{}] Log text".format(time.strftime('%X')) + WHITE)
        print(BLUE + "Enter your input >" + WHITE, end = ' ', flush=True)
        time.sleep(2)

This has an output like this : gif of my console for modified version

I've tried various options from this question but all of them are for single thread processes where input() and print() are in series.

I'm looking for a cleaner solution to both of them working in parallel. Is there any way to store the characters user has already typed before pressing return key or any other method that can be implemented to make the two threads work in harmony on the same console?

arpitm91
  • 29
  • 5
  • 2
    This isn't really a Python problem. Both `input()` and `print()` write directly to `sys.stdout` and that's not really a stream that handles interleaving. Have you considered using `curses` to talk to the terminal and divvy it up into regions? One for user interaction, the other for log entries. – Martijn Pieters Mar 07 '18 at 21:18
  • @MartijnPieters I wasn't aware of the `curses` library. Thanks for giving me a proper direction. I'll try to create a solution from its [documentation](https://docs.python.org/2/library/curses.html). Can you please point me which curses member functions would be important in creating the regions? – arpitm91 Mar 07 '18 at 22:34
  • Curses is quite low-level, you may want to look at a wrapper like http://urwid.org/ to give you ready-made UI components. – Martijn Pieters Mar 08 '18 at 07:44

0 Answers0