2020-11-28 - Keypresses in Python ------------------------------------------------------------------- For my work i was building a simple data logger in Python. And the first version consisted of a fairly fancy application built using the Tkinter and matplotlib libraries. And while this was fun to do, i also wanted to create a simpler, more basic version of the logger that was independent on any external libraries. So the fancy GUI and live plotting capabilities were dumped in order to write a simple CLI application. I wanted the program to be a bit interactive, showing a menu from where datalogging could be started. Once the datalogging is started, a keypress should stop the logging and return to the main menu. Funnily enough, i found out vanilla python on Windows is unable to detect keypresses without importing some external libary such as Pyinput or (Py)Keyboard. I believe on Linux the Curses library is built into Python by default, but this is not the case on Windows (which is the target for my little script). As i did not need very fancy keypress handling, i didn't want to use an external library just to abort datalogging with a press. So therefore i opted to catch Python's KeyboardInterrupt and build my little program around this as follows: ------------------------------------------------------------------ import time def print_menu(): print("-----------------------------------") print("1: Start Recording (Ctrl-C to stop)") print("0: Quit") print("-----------------------------------") c = input("Choice: ") if c == '1': while 1==1: print ("Recording...") time.sleep(1) elif c=='0': exit() if __name__ == '__main__': while 1==1: try: print_menu() except KeyboardInterrupt as e: pass e.__traceback__ = None ------------------------------------------------------------------ So the main program keeps looping to show the print_menu, and once the user chooses to start Recording, the Recording loop runs, until Ctrl-C is pressed,and the print_menu is shown again. This works pretty nicely, and this way i can interrupt the logging with a keypress (Ctrl-C) without needing an external library. But as i'm writing this, i am starting to think this program is not good practice at all for a proper Unix-way of working. Instead of writing the script as outlined above, i should change the program to use command line arguments, and use std. in/output. So instead of an "interactive" program with a menu, the program should just start recording directly after it has been started with a certain commandline argument. And it should output its data directly over stdout. This would perhaps be a more unix-like way of doing this, and will make it more useful on the commandline. I think it is time to re-read "The Art of Unix Programming" by Eric S Raymond again.