0

Im trying to make a countdown timer with the feature to reset/stop/pause/resume. I tried implementing an if/elif/else statement to check for user input letter within the while loop while it continues looping. However, the loop stops running when the conditional statement executes. How do I implement my intended functionality into the code?

code:

 import time
 import datetime

 def timeinput():
  # Inputs for hours, minutes, seconds on timer
  h = input("Enter the time in hours: ")
  m = input("Enter the time in minutes: ")
  s = input("Enter the time in seconds: ")
  countdown(int(h), int(m), int(s))

# Create class that acts as a countdown
 def countdown(h, m, s):
  # Print options for user to do
  print("Press w to reset \nPress s to stop \nPress a to pause \nPress d to resume")

  # Calculate the total number of seconds
  total_seconds = h * 3600 + m * 60 + s

  # 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)
    
    # Prints the time left on the timer
    print(timer, end="\r")
    
    # Delays the program one second
    time.sleep(1)

    # Reduces total time by one second
    total_seconds -= 1
    user=input()
    
    if user=="w":
      total_seconds=0
      print("Timer will now reset")
      timeinput()

   print("Bzzzt! The countdown is at zero seconds!")

  timeinput()

result: outcome of code

As shown in the provided image, the loop stops at 20 secs. My intended action here was for the countdown to continue until the user presses the W key, which shall then reset the countdown back to its original set time at initialization.

4 Answers4

2

Soo, I'm also kinda new to programming and python so I don't exactly how to make a timer with that functionality. What is happening is that when you use the input() function the code stops and waits for the user input.

I know you can use some libraries, like pygame, in order to check for user input inside the loop without stopping it, but without one I'm not sure how to do it.

You can also use the module keyboard, that comes inside python, and I think is great for the problem you shared. Check this post How to detect key presses?

1

The command input() is blocking. It waits until it get something from the console. Maybe take a look at this post and try to implement a non blocking version of input. Non-blocking console input?

Tomás Mendes
  • 58
  • 1
  • 7
1

The problem is that input is blocking - that is, it will stop the execution until the user presses < enter> .

Antique running environments, on 8 bit computers, using Basic, could check "what the user is pressing right now", without waiting for a confirmation with "enter" using the inkey command.

In Python programs running on terminal, terminedia, a 3rdy party library, implements inkey() as it was - but it needs the terminal input to be reconfigured for which it provides a "keyboard" context manager.

You can then run almost the same code you have -just install terminedia in your Python environment with "pip install terminedia"

import terminedia as TM

...

 def countdown(h, m, s):
  ...
  while total_seconds > 0:

    # Timer represents time left on countdown
    timer = datetime.timedelta(seconds = total_seconds)
    
    # Prints the time left on the timer
    print(timer, end="\r")
    
    with TM.keyboard:
        # Delays the program one second
        time.sleep(1)

        # Reduces total time by one second
        total_seconds -= 1
        user=TM.inkey()
        
    if user=="w":
      total_seconds=0
      print("Timer will now reset")
      timeinput()

   print("Bzzzt! The countdown is at zero seconds!")

  timeinput()

(disclaimer: I am terminedia author)

jsbueno
  • 99,910
  • 10
  • 151
  • 209
  • Thank you so much for your answer, but i already solved the issue i was facing using pygame suggested in one of the earlier answers. However i did gain new insight through what you suggested. I shall try it out too. – Marka Ragnos Sep 28 '22 at 20:25
  • 1
    Yes - pygame has teh same functionality of non-blocking keyboard read - the drawback in thsio case is that it can only read the keyboard events on the window it creates - which lacks a buffered text output with scrolling. If you can rewrite you app for displaying text in pygame window, though, you can add mouse support and a lot of awesome stuff. – jsbueno Sep 28 '22 at 20:36
0

Taking inputs from the answers received here and subsequent follow-up questions on stack overflow and Reddit, this question has been solved using pygame. I'll provide the link below for future reference to this question.

problem solution