Skip to content

Instantly share code, notes, and snippets.

@groner
Created December 14, 2020 23:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save groner/b06262f5c57e52edfe993c3ec1229ba5 to your computer and use it in GitHub Desktop.
Save groner/b06262f5c57e52edfe993c3ec1229ba5 to your computer and use it in GitHub Desktop.
stopwatch for terminal (python)
#!/bin/env python3
import argparse
from contextlib import contextmanager
from datetime import datetime
from datetime import timedelta
from select import select
import termios
def main():
parser = argparse.ArgumentParser()
parser.add_argument('step', metavar='STEP', nargs='?', default='0.1',
help='time interval in seconds to update display')
parser.add_argument('-p', '--precision', metavar='PRECISION', type=int,
help='how many decimal places to show in seconds, defaults to the number in STEP')
args = parser.parse_args()
precision = args.precision
if precision is None:
precision = precision_of(args.step)
stopwatch(float(args.step), precision)
def stopwatch(step, precision):
# timedelta formats with microseconds, we want to trim any excess decimals
prec_pos = -6+precision
if prec_pos == -6:
prec_pos = -7
fmt = lambda s: str(s)[:prec_pos]
# format is fixed width, so don't worry about clear to EOL
t0 = datetime.now()
with no_icanon_no_echo():
while True:
print(f'\r{fmt(datetime.now()-t0)}', end='')
r,_,x = select([0], [], [0], step)
if r or x:
break
print(f'\r{fmt(datetime.now()-t0)}')
def precision_of(f):
# try to determine how much precision was specified after the decimal
if isinstance(f, str):
s = f
else:
s = f'{f:10f}'.rstrip('0')
if '.' in s:
return len(s.split('.', 1)[1])
return 0
@contextmanager
def no_icanon_no_echo(fd=0):
iflag, oflag, cflag, lflag, ispeed, ospeed, cc = termios.tcgetattr(fd)
termios.tcsetattr(fd, termios.TCSANOW, [
iflag,
oflag,
cflag,
lflag & ~termios.ICANON & ~termios.ECHO,
ispeed,
ospeed,
cc])
try:
yield
finally:
termios.tcflush(fd, termios.TCIFLUSH)
termios.tcsetattr(fd, termios.TCSANOW, [
iflag,
oflag,
cflag,
lflag,
ispeed,
ospeed,
cc])
if __name__ == '__main__':
main()
@CodeMan99
Copy link

Neat. Free lap-counter mode:

while true; do { ./stopwatch.py 0.01; } done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment