Creating a Countdown Timer Using Python

Creating a Countdown Timer Using Python

ECX 30 Days of Code and Design

Day 20

Task

Write a program that:

  • Asks the user to enter a time duration in the form of a number with a unit of either seconds, minutes, or hours. (E.g., "44s", "32m", "10h")
  • The last character of the string entered would be used to determine its unit
  • Counts down from the input value, and prints out the time left on the clock every second
  • When the time is exhausted, makes a beeping sound non-stop until the user exits the app For example:
    T > Enter a time
    User > 5s
    T > 5 seconds left
    > 4 seconds left
    > 3 seconds left
    > 2 seconds left
    > 1 second left
    Continuous indefinite beeping
    
    Hint: A "beeping sound" can be achieved using the "bell character", or any library of your choice.

My Approach

This is the full code. It would be explained in bits throughout this article.

import time                    # For sleep
import datetime                # For timedelta
# import winsound                # For Beep on Windows OS


# Countdown timer function
def countdown(hrs, mins, sec):
    """Counts down time and gives off beeps when the time inputted elapse"""
    # Calculate the total number of seconds
    total_seconds = hrs * 3600 + mins * 60 + sec

    # While loop that checks if total_seconds reaches zero
    # If not zero, decrement total time by one second

    while total_seconds >= 0:

        # Timer represents time left on countdown
        timer = datetime.timedelta(seconds=total_seconds)
        print(timer, end='\r')

        # Delays the program one second
        time.sleep(1)

        # Reduces total time by one second
        total_seconds = total_seconds - 1

    # The timer continually beeps for the next 45 seconds
    alarm_sec = 45
    while alarm_sec > 0:
        # winsound.Beep(440, 500)
        print('\a', end='\r')
        time.sleep(1)
        alarm_sec -= 1


# User Input
try:
    hours = input("Enter the time in hours: ")
    minutes = input("Enter the time in minutes: ")
    secs = input("Enter the time in seconds: ")

    countdown(int(hours), int(minutes), int(secs))
except ValueError:
    print('Invalid input! Only integers are allowed.')

First, we import the time, datetime, and winsound modules. You would notice the winsound module is commented; that is because the bell character (‘\a’) did not work on my Windows PC, so I had to use the winsound module, but the bell character worked on Replit, but not the winsound module; so, I have left it there should incase the bell characters fails to work, the winsound can be used.

import time                    # For sleep
import datetime                # For timedelta
# import winsound                # For Beep

Next, we define the function, countdown(), which takes three parameters (hours, minutes, and seconds). We then create a variable, total_seconds, which calculates the number of seconds based on the input of the user. 1 hour has 3600 seconds (60 * 60) and 1 minute has 60 seconds.

def countdown(hrs, min, sec):
    total_seconds = hrs * 3600 + min * 60 + sec

Using while loop, we count down the number of seconds. We pass the number of seconds into the timedelta() function which gives X days, hh:mm:ss format if we exceed 86400 seconds (1 day), but if the seconds is less than 86400, we have it formatted to hh:mm:ss. We print out the current time remaining; then use the sleep() function from the time module to sleep the program for a second and deduct the time. We continue this until we get to zero seconds. Carriage return '\r' is used here to ensure that our timer is displayed on a single line; that is, as we display the number of seconds left, the previous output is overwritten, and the new output takes that space of the previous output.

    while total_seconds > 0:

        # Timer represents time left on countdown
        timer = datetime.timedelta(seconds=total_seconds)
        print(timer, end='\r')

        # Delays the program one second
        time.sleep(1)

        # Reduces total time by one second
        total_seconds = total_seconds - 1

When the timer is up, we would have a continuous beeping from the bell character for 45 seconds (the task was that the bell should go until the program is interrupted, but I was advised that it could have an adverse effect on the PC. To make it continuous use while True:. If the bell character fails to produce a sound and you are on Windows OS, you can uncomment thewinsound.Beep(440, 500)`. The first argument (440) indicates the frequency of the beep in hertz, while the second argument (500) implies the duration of the beep in milliseconds.

    alarm_sec = 45
    while alarm_sec > 0:
        # winsound.Beep(440, 500)
        print('\a', end='\r')
        time.sleep(1)
        alarm_sec -= 1

Finally, we ask for the user input, and pass them as arguments into the function. We make use of try except block to handle ValueError try: hours = input("Enter the time in hours: ") minutes = input("Enter the time in minutes: ") secs = input("Enter the time in seconds: ")

countdown(int(hours), int(minutes), int(secs))

except ValueError: print('Invalid input! Only integers are allowed.')

Output

Run the code on my Replit.