first commit, working through CLI
This commit is contained in:
134
random_timer.py
Executable file
134
random_timer.py
Executable file
@@ -0,0 +1,134 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Catchphrase
|
||||||
|
Author: Jerick Oates
|
||||||
|
"""
|
||||||
|
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# ---------- CONFIG ----------
|
||||||
|
WORDS_FILE = "words.txt" # file with one word per line
|
||||||
|
TIMER_SECONDS = 30 # how long the timer runs
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- HELPERS ----------
|
||||||
|
def load_words(path=WORDS_FILE):
|
||||||
|
"""Return a list of non‑empty stripped lines from the given file."""
|
||||||
|
try:
|
||||||
|
with open(path, "r", encoding="utf-8") as f:
|
||||||
|
words = [line.strip() for line in f if line.strip()]
|
||||||
|
if not words:
|
||||||
|
raise ValueError("Word file is empty.")
|
||||||
|
return words
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error loading words: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def pick_random(words):
|
||||||
|
"""Return a random word from the list."""
|
||||||
|
return random.choice(words)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- TIMER THREAD ----------
|
||||||
|
class CountdownTimer(threading.Thread):
|
||||||
|
"""
|
||||||
|
Background thread that counts down for TIMER_SECONDS.
|
||||||
|
When it finishes, it calls an optional callback.
|
||||||
|
"""
|
||||||
|
def __init__(self, seconds=TIMER_SECONDS, on_finish=None):
|
||||||
|
super().__init__()
|
||||||
|
self.seconds = seconds
|
||||||
|
self.on_finish = on_finish # function to call when timer ends
|
||||||
|
self._running = threading.Event()
|
||||||
|
self._running.set()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
for _ in range(self.seconds):
|
||||||
|
if not self._running.is_set():
|
||||||
|
break # stopped early by user
|
||||||
|
time.sleep(1)
|
||||||
|
# Timer finished (or was stopped)
|
||||||
|
self._running.clear()
|
||||||
|
if self.on_finish:
|
||||||
|
self.on_finish() # announce completion
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""Stop the timer before it reaches zero."""
|
||||||
|
self._running.clear()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_running(self):
|
||||||
|
return self._running.is_set()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- MAIN LOOP ----------
|
||||||
|
def main():
|
||||||
|
words = load_words()
|
||||||
|
timer_thread = None
|
||||||
|
|
||||||
|
print("=== Catchphrase ===")
|
||||||
|
print("Commands:")
|
||||||
|
print(" start – begin the 30‑second timer and show a word immediately")
|
||||||
|
print(" next – show another random word while the timer is running")
|
||||||
|
print(" stop – cancel the timer early")
|
||||||
|
print(" exit / quit – leave the program")
|
||||||
|
|
||||||
|
# Helper that prints when the timer ends
|
||||||
|
def announce_finish():
|
||||||
|
print("\n⏰ Time’s up! Returning to menu.")
|
||||||
|
print("=== Catchphrase ===")
|
||||||
|
print("Commands:")
|
||||||
|
print(" start – begin the 30‑second timer and show a word immediately")
|
||||||
|
print(" next – show another random word while the timer is running")
|
||||||
|
print(" stop – cancel the timer early")
|
||||||
|
print(" exit / quit – leave the program")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
cmd = input("\n> ").strip().lower()
|
||||||
|
except EOFError: # Ctrl‑D
|
||||||
|
break
|
||||||
|
|
||||||
|
if cmd in ("exit", "quit"):
|
||||||
|
if timer_thread and timer_thread.is_running:
|
||||||
|
timer_thread.stop()
|
||||||
|
timer_thread.join()
|
||||||
|
print("👋 Goodbye!")
|
||||||
|
break
|
||||||
|
|
||||||
|
elif cmd == "start":
|
||||||
|
if timer_thread and timer_thread.is_running:
|
||||||
|
print("[!] Timer is already running.")
|
||||||
|
else:
|
||||||
|
# Start a new timer with the finish callback
|
||||||
|
timer_thread = CountdownTimer(on_finish=announce_finish)
|
||||||
|
timer_thread.daemon = True # exit when main thread exits
|
||||||
|
timer_thread.start()
|
||||||
|
|
||||||
|
# Show the first word right away
|
||||||
|
print(pick_random(words))
|
||||||
|
print(f"[+] 30‑second timer started. ({TIMER_SECONDS}s)")
|
||||||
|
|
||||||
|
elif cmd == "next":
|
||||||
|
if not (timer_thread and timer_thread.is_running):
|
||||||
|
print("[!] No active timer – use 'start' first.")
|
||||||
|
else:
|
||||||
|
print(pick_random(words))
|
||||||
|
|
||||||
|
elif cmd == "stop":
|
||||||
|
if timer_thread and timer_thread.is_running:
|
||||||
|
timer_thread.stop()
|
||||||
|
timer_thread.join()
|
||||||
|
print("[+] Timer stopped early.")
|
||||||
|
else:
|
||||||
|
print("[!] There is no running timer to stop.")
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(f"[!] Unknown command: {cmd}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user