Analog stopwatch using Python turtle module
In this tutorial, let’s build an analog stopwatch using Python’s turtle module. Let us have a circular representation of hours, minutes and seconds as distance traversed by the respective turtles.
Turtle movement calculations:
- The seconds hand of an analog clock traverses 6 degrees every second
- The minute hand traverses 6 degrees every minute; 1 min = 60 seconds -> therefore minute hand traverses 6/60 degrees every second.
- The hour hand traverses 30 degrees every hour; 1 hour = 3600 seconds -> therefore hour hand traverses 30/3600 degrees every second
Using these traversal calculations we create 3 turtles and move them every second after a fixed delay. This delay plus the time taken to traverse all the three triangle’s each time must be equal to 1000 milliseconds to ensure that it takes 1 second in all for each tick.
We need to import turtle,time, keyboard and math modules.
Here on running the script, stop watch begins immediately. The clock can be paused in between and resumed after sometime or the stop watch can be stopped altogether as per the user’s requirements.
Here we are using “KeyboardInterrupt” from keyboard module to pause/resume and to stop the timer. The user can press “ctrl+c” to interrupt the stop watch (try block) and as a result pause the timer. After generating keyboard interrupt by pressing ctrl+c press “space” to resume the stop watch or press “esc” to stop the stopwatch completely.
Note: This script must be run in the terminal as often IDE’s have “ctrl+c” command as the shortcut for copying text.
Code:
import turtle # import turtle for graphical representation of analog stop watch clock import time import time # importing time to measure time and track duration import keyboard # to use keyboard interrupt import math print(""" To pause the stopwatch kindly press ctrl+c.\n To resume the stop watch press "space" to resume the stop watch or press "esc" if you wish to stop the stopwatch\n Stop watch begins!\n """) second_extent = 6 # second hand traverses 6 degrees every second in a clock minute_extent = 6 / 60 # minute hand traverses 6 degrees every minute so it traverses 6/60 degrees every second hour_extent = 30 / 3600 # hour hand traverses 30 degrees every hour so it traverses 30/3600 degrees every second second_turtle = turtle.Turtle() # creating a turtle that represents seconds traversed minute_turtle = turtle.Turtle() # creating a turtle that represents minutes traversed hour_turtle = turtle.Turtle() # creating a turtle that represents hours traversed window = turtle.Screen() window.bgcolor("#F5F0E1") # Half white background of turtle screen window.setup(400, 400) # changing turtle window size for aesthetics of the window def circle_draw(): # function to move turtles every second_turtle.circle(-100, extent=second_extent) # note: radius is negative to move the turtles in clockwise direction minute_turtle.circle(-120, extent=minute_extent) hour_turtle.circle(-140, extent=hour_extent) def turtle_settings(): # turtle speeds second_turtle.speed(0) minute_turtle.speed(0) hour_turtle.speed(0) # turtle colors second_turtle.color("#1E3D59") # blue minute_turtle.color("#FF6E40") # orange hour_turtle.color("#FFC13B") # yellow # turtle pen sizes/ stroke sizes hour_turtle.pensize(4) minute_turtle.pensize(3) second_turtle.pensize(2) # second hand turtles starting position second_turtle.penup() second_turtle.goto(0, 100) second_turtle.pendown() # minute hand turtles starting location minute_turtle.penup() minute_turtle.goto(0, 120) minute_turtle.pendown() # hour hands starting location hour_turtle.penup() hour_turtle.goto(0, 140) hour_turtle.pendown() def turtle_reset(): second_turtle.reset() minute_turtle.reset() hour_turtle.reset() def time_conversion(time_elapsed): # converting seconds to hours:minutes:seconds format hour = math.floor(time_elapsed / 3600) minute = math.floor((time_elapsed % 3600) / 60) second = round((time_elapsed % 3600) % 60) print(f'Time elapsed: {hour}:{minute}:{second}\n') turtle_settings() # setting up the turtles with customisation and positions calibration_start = time.time() # here determining the time required to move a the three turtles every sec circle_draw() calibration_end = time.time() draw_time = (calibration_end - calibration_start) # calculating time taken to move the three turtles # print(draw_time) uncomment and clear this comment to see the time required to move the three turtles each time in milliseconds turtle_reset() # calling turtle reset to clear the drawings and turtle settings turtle_settings() # turtle settings to customise turtles and assign their positions ''' delay between any two function calls of circle draw to ensure that that time gap between any two calls and the time to taken to move the three turtles together makes 1000 milliseconds ''' compensated_delay = int(1000 - round((1000 * draw_time), 3)) # subtracting drawing time to ensure timing accuracy # print(compensated_delay) uncomment this line to see the compensated delay elapsed_time = 0 start = time.time() while True: try: turtle.ontimer(circle_draw(), compensated_delay) # if the stop watch is interrupted by ctrl+c command then the except block of the code executes except KeyboardInterrupt: elapsed_time = elapsed_time + time.time() - start time_conversion(elapsed_time) # converting seconds to hours:minutes:seconds format # to stop timer and halt program until the stopwatch is resumed or terminated again by pressing the respective key status = keyboard.read_key() if status == 'space': # space to resume stop watch again start = time.time() elif status == 'esc': # esc to stop the stop watch completely print("Stop watch terminated") break window.bgcolor("#C6D7EB") # changing background color of turtle window to indicate end of stopwatch window.exitonclick() # to prevent turtle screen from shutting down immediately after the stop watch stops
Output:
C:\Users\User\PycharmProjects\CodeSpeedy>python analog_stopwatch.py To pause the stopwatch kindly press "ctrl+c". To resume the stop watch press "space" or press "esc" if you wish to stop the stopwatch Stop watch begins! Time elapsed: 0:19:59
Time elapsed: 0:20:57
Stop watch terminated
Leave a Reply