Skip to content

Instantly share code, notes, and snippets.

@antonl-dev
Created March 13, 2026 10:24
Show Gist options
  • Select an option

  • Save antonl-dev/fcf24979f827557da07f50ee1dd140fe to your computer and use it in GitHub Desktop.

Select an option

Save antonl-dev/fcf24979f827557da07f50ee1dd140fe to your computer and use it in GitHub Desktop.
import time
import sys
# --- Cross-Platform code to read single key presses without pressing Enter ---
try:
import msvcrt # Works on Windows
def get_key():
return msvcrt.getch().decode('utf-8', 'ignore').lower()
except ImportError:
import tty, termios # Works on Mac/Linux
def get_key():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch.lower()
# ----------------------------------------------------------------------------
def main():
print("=======================================")
print(" 🚲 MTB CLI Cadence Calculator 🚲 ")
print("=======================================")
print("Press 'A' for Left foot downstroke")
print("Press 'D' for Right foot downstroke")
print("Press 'Q' to quit.")
print("-" * 39)
print("Start tapping to the rhythm of your pedaling...\n")
timestamps = []
while True:
key = get_key()
if key == 'q':
print("\n\nRide finished. 🌴")
break
if key in ['a', 'd']:
now = time.time()
# If you stopped tapping for more than 2 seconds, reset the math
if len(timestamps) > 0 and (now - timestamps[-1]) > 2.0:
timestamps.clear()
sys.stdout.write("\r" + " " * 40 + "\r") # Clear the line
sys.stdout.write("\r⏳ Resuming... keep tapping! ")
sys.stdout.flush()
timestamps.append(now)
# Keep the last 10 presses (5 full revolutions) for a smooth average
if len(timestamps) > 10:
timestamps.pop(0)
# Need at least 3 taps (1 full revolution) to calculate RPM
if len(timestamps) >= 3:
time_diff = timestamps[-1] - timestamps[0]
# Number of downstrokes = total taps minus 1.
# Divide by 2 to get full revolutions.
revolutions = (len(timestamps) - 1) / 2.0
if time_diff > 0:
rpm = (revolutions / time_diff) * 60
# Create a visual bar based on speed
bar = "█" * int(rpm / 5)
# Print over the same line repeatedly
sys.stdout.write(f"\r🚴 Cadence: {rpm:05.1f} RPM | {bar.ljust(20)}")
sys.stdout.flush()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment