Aug-02-2022, 01:39 PM
You need something, which calls for example on
You can record for each
In addition, you can also count words, but this requires additional work to get it correctly.
Example with tkinter:
KeyPress
a callback, which does the logic.You can record for each
KeyPress
a timestamp/timeout in a list. Another repeated function could delete the data which is for example older than 5 seconds. This is your observation window. To get the KeyPress per minute, count the elements after old values have been deleted from the list and then divide it by observation window and multiply by 60.In addition, you can also count words, but this requires additional work to get it correctly.
Example with tkinter:
import time from threading import Lock from tkinter import END, Button, Label, StringVar, Text, Tk, INSERT class KPM: def __init__(self, time_window): self.time_window = time_window self.lock = Lock() self.window = Tk() self.kpm = StringVar() self.wpm = StringVar() Label(self.window, textvariable=self.kpm, font=36).pack() Label(self.window, textvariable=self.wpm, font=36).pack() self.text_widget = Text(self.window, font=24) self.text_widget.pack() Button(self.window, text="Clear", command=self._clear).pack() Button(self.window, text="Exit", command=self.window.destroy).pack() self.window.bind_all("<KeyPress>", self.on_press) self.strokes = [] self.words = [] self._last_char = None self._show() def _clear(self): self.text_widget.delete("1.0", END) self.strokes.clear() self.words.clear() def _show(self): with self.lock: now = time.monotonic() self.strokes = [timeout for timeout in self.strokes if now < timeout] self.words = [timeout for timeout in self.words if now < timeout] kpm = len(self.strokes) / self.time_window * 60 wpm = len(self.words) / self.time_window * 60 self.kpm.set(f"{kpm:.0f} key presses per minute") self.wpm.set(f"{wpm:.0f} words per minute") self.window.after(200, self._show) def on_press(self, event): with self.lock: timeout = time.monotonic() + self.time_window self.strokes.append(timeout) # cursor_position = self.text_widget.index(INSERT) # too complicated to look backwwards ... if event.char == " " and self._last_char != " ": self.words.append(timeout) self._last_char = event.char def start(self): self.window.mainloop() if __name__ == "__main__": KPM(time_window=5).start()Other libraries which can read keyboard events:
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
All humans together. We don't need politicians!