-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Examples of using that keystroke reader thing.
- Loading branch information
1 parent
0dfdcc1
commit 0f35017
Showing
2 changed files
with
204 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" | ||
A (unix terminal) stopwatch utility. | ||
""" | ||
|
||
import logging | ||
import sys | ||
import time | ||
|
||
from pyutils import bootstrap, config, input_utils | ||
|
||
logger = logging.getLogger(__name__) | ||
args = config.add_commandline_args(f'({__file__})', f'Args related to {__file__}') | ||
args.add_argument("--start", action="store_true", help="Start as soon as possible.") | ||
|
||
|
||
class Stopwatch: | ||
def __init__(self): | ||
self.running = False | ||
self.start_time = 0.0 | ||
self.elapsed_time = 0.0 | ||
|
||
def start(self): | ||
if not self.running: | ||
self.start_time = time.time() | ||
self.running = True | ||
|
||
def pause(self): | ||
if self.running: | ||
self.elapsed_time += time.time() - self.start_time | ||
self.running = False | ||
|
||
def reset(self): | ||
self.running = False | ||
self.start_time = 0 | ||
self.elapsed_time = 0 | ||
|
||
def get_elapsed_time(self) -> float: | ||
if self.running: | ||
return self.elapsed_time + time.time() - self.start_time | ||
else: | ||
return self.elapsed_time | ||
|
||
|
||
@bootstrap.initialize | ||
def main(): | ||
print("Stopwatch... [space]=stop/start, [l]ap, [r]eset, [q]uit (or ^C)") | ||
stopwatch = Stopwatch() | ||
if config.config["start"]: | ||
stopwatch.start() | ||
|
||
with input_utils.KeystrokeReader() as get_keystroke: | ||
while True: | ||
# Check / parse any keys. | ||
key = get_keystroke(timeout_seconds=0.01) | ||
if key: | ||
if key == ' ': | ||
if not stopwatch.running: | ||
stopwatch.start() | ||
else: | ||
stopwatch.pause() | ||
elif key == 'r': | ||
print(" " * 50, end='\r') | ||
stopwatch.reset() | ||
elif key == 'l': | ||
print(f"Lap: {stopwatch.get_elapsed_time():.5f}", end="\r\n") | ||
elif key == 'q' or key == chr(3): | ||
print() | ||
return | ||
|
||
# Update display. | ||
print(f"Elapsed time: {stopwatch.get_elapsed_time():0.4f}", end="\r") | ||
sys.stdout.flush() | ||
return None | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" | ||
A (unix terminal) countdown timer utility. | ||
""" | ||
|
||
import logging | ||
import sys | ||
import time | ||
from typing import Optional | ||
|
||
from pyutils import argparse_utils, bootstrap, config, input_utils | ||
|
||
logger = logging.getLogger(__name__) | ||
args = config.add_commandline_args(f'({__file__})', f'Args related to {__file__}') | ||
args.add_argument( | ||
"time_limit", | ||
type=argparse_utils.valid_duration, | ||
help="The time limit of the countdown timer.", | ||
) | ||
args.add_argument( | ||
"--infinite", | ||
action="store_true", | ||
help="After the timer expires, reset and start again forever.", | ||
) | ||
args.add_argument( | ||
"--pause_between", | ||
action="store_true", | ||
help="Should we pause between adjacent timer runs.", | ||
) | ||
|
||
|
||
class Timer: | ||
def __init__(self, duration: float): | ||
self.running = True | ||
self.start = time.time() | ||
self.original_duration = duration | ||
self.duration = duration | ||
self.run_number = 1 | ||
self.elapsed_before_pause = 0.0 | ||
|
||
def get_remaining_time(self) -> float: | ||
return self.original_duration - self.get_elapsed_time() | ||
|
||
def get_elapsed_time(self) -> float: | ||
if self.running: | ||
now = time.time() | ||
return now - self.start + self.elapsed_before_pause | ||
else: | ||
return self.elapsed_before_pause | ||
|
||
def is_expired(self): | ||
elapsed = self.get_elapsed_time() | ||
return elapsed >= self.original_duration | ||
|
||
def reset(self): | ||
self.run_number += 1 | ||
self.start = time.time() | ||
self.duration = self.original_duration | ||
self.elapsed_before_pause = 0 | ||
self.running = True | ||
|
||
def reset_and_pause(self): | ||
self.run_number += 1 | ||
self.start = time.time() | ||
self.duration = self.original_duration | ||
self.elapsed_before_pause = 0 | ||
self.running = False | ||
|
||
def pause(self): | ||
self.elapsed_before_pause = self.get_elapsed_time() | ||
self.running = False | ||
|
||
def unpause(self): | ||
self.start = time.time() | ||
self.duration = self.original_duration - self.elapsed_before_pause | ||
self.running = True | ||
|
||
|
||
@bootstrap.initialize | ||
def main() -> Optional[int]: | ||
duration = config.config["time_limit"] | ||
timer = Timer(duration.seconds) | ||
print("Countdown timer... [space]=pause/unpause, [r]eset, [q]uit (or ^C).") | ||
|
||
with input_utils.KeystrokeReader() as get_keystroke: | ||
while True: | ||
|
||
# Check for input / parse any. | ||
key = get_keystroke(timeout_seconds=0.01) | ||
if key: | ||
if key == ' ': | ||
if timer.running: | ||
timer.pause() | ||
else: | ||
timer.unpause() | ||
elif key == 'r': | ||
print(end="\r\n") | ||
timer.reset() | ||
elif key == 'q' or key == chr(3): | ||
sys.exit(0) | ||
|
||
# Display remaining countdown. | ||
remaining = timer.get_remaining_time() | ||
print(f"{remaining:0.2f} ", end='\r') | ||
|
||
# Done? | ||
if timer.is_expired(): | ||
if not config.config["infinite"]: | ||
print("Beep, beep, beep!", end="\r\n") | ||
sys.exit(0) | ||
|
||
print( | ||
f"Run number {timer.run_number} expired... Beep, beep, beep!", | ||
end="\r\n", | ||
) | ||
if config.config["pause_between"]: | ||
timer.reset_and_pause() | ||
else: | ||
timer.reset() | ||
return None | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |