Archive

Posts Tagged ‘console’

monitoring key presses in a console application in a thread

November 16, 2019 Leave a comment

Problem
I wrote a console application that shows a table and updates the screen every second. Later, I wanted to add a table sorting functionality. For instance, if you press ‘b’, then the table is sorted by the 2nd column, pressing ‘c’ would sort the table by the 3rd column, etc.

I found some keyboard monitoring libraries but they were all blocking, i.e. you had to call a function which was waiting for a key press. If you didn’t press any key, this function was just waiting.

However, in my program I had an infinite loop that was doing the following steps: (1) clear the screen, (2) draw the table, (3) repeat. If I add anywhere the keyboard monitoring, the loop gets blocked somewhere.

Solution
I asked this question on reddit (see here), and /u/Viddog4 suggested that I should use a thread. Of course! I have the main loop that draws the table, and I have a thread in the background that monitors the keyboard.

Here is a simplified code that demonstrates the idea:

#!/usr/bin/env python3

"""
pip3 install pynput xlib
"""

import threading
from time import sleep

from pynput.keyboard import Key, Listener


class myThread(threading.Thread):
    def __init__(self, _id, name):
        super().__init__()
        self.daemon = True    # daemon threads are killed as soon as the main program exits
        self._id = _id
        self.name = name

    def on_press(self, key):
        print('{0} pressed'.format(key))

    def on_release(self, key):
        print('{0} release'.format(key))
        if key == Key.esc:
            # Stop listener
            return False

    def run(self):
        with Listener(on_press=self.on_press, on_release=self.on_release) as listener:
            listener.join()


def main():
    thread1 = myThread(1, "thread_1")
    thread1.start()
    # main loop:
    while True:
        print(".", flush=True)
        try:
            sleep(1)
        except KeyboardInterrupt:
            break

##########

if __name__ == "__main__":
    main()

You can stop the thread with Esc. You can terminate the whole program with Ctrl+C. The thread is registered as a daemon thread, which means that if the main program exits (e.g. you press Ctrl+C), then daemon threads are automatically stopped.

Links

Categories: python Tags: , , ,

flush the stdin

November 16, 2019 Leave a comment

Problem
I wrote a terminal application that was reading key presses from the keyboard using the pynput library. When the program terminated, it printed on the screen the keys that I pressed while the program was running. How to get rid of this side effect?

Solution
First I tried sys.stdin.flush() but it didn’t help. However, the following worked:

import sys
import termios

termios.tcflush(sys.stdin, termios.TCIOFLUSH)

Calling this line before quitting successfully flushed the standard input.

Categories: python Tags: , , ,

[nodejs] raw_input in Node.js

November 7, 2015 Leave a comment

Problem
How to read in Node.js from the console? For instance, how to rewrite the following Python script?

n1 = int(raw_input("1st number: "))
n2 = int(raw_input("2nd number: "))

print "The sum is:", n1+n2

Solution

#!/usr/bin/env node

"use strict";

var readline = require('readline');

var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

function processNums(n1, n2) {
    n1 = Number(n1);
    n2 = Number(n2);
    console.log("Their sum: " + (n1 + n2));
}

function start() {
    rl.question('1st number: ', function (x) {
        rl.question('2nd number: ', function (y) {
            rl.close();

            processNums(x, y);
        });
    });
}

function main() {
    start();
}

main();

Tip from here.

Categories: nodejs Tags: , ,