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.