0

I'm relatively new to Python so I don't know how difficult or easy this is to solve, but I'm trying to make a function that can measure time without blocking other code from executing while doing so. Here's what I have:

import time

def tick(secs):
    start = time.time()
    while True:
        end = time.time()
        elapsed = end - start
        if elapsed >= secs:
            return elapsed
            break


input("what time is it?: ")
print(f"one: {round(tick(1))}")
print(f"two: {round(tick(2))}")
print(f"three: {round(tick(3))}")
print(f"four: {round(tick(4))}")
print(f"five: {round(tick(5))}")

The input blocks the timer from starting until it gets input, and the tick()'s after dont run simultaneously. Thus running one at a time like, wait 1 second then wait 2 seconds instead of wait 5 seconds (to be clear I want all timers that are started to run at the same time others are, so the 5 second timer would start at the same time the 1 second one does), thank you for your time and please let me know if you have a solution for this.

CATboardBETA
  • 418
  • 6
  • 29

2 Answers2

0

Not exactly sure what you are asking for, but how does this look:

import time
start=time.time()
input("what time is it?: ")

time.sleep(1)
print(time.time()-start)
time.sleep(2)
print(time.time()-start)
time.sleep(3)
print(time.time()-start)
time.sleep(4)
print(time.time()-start)
time.sleep(5)
print(time.time()-start)
user1763510
  • 1,070
  • 1
  • 15
  • 28
0

The tick's are not running simultanously because your are first waiting for 1 second, then again you are waiting for 2, then again for 3, etc.

A simple thing to do is have a list of time intervals you want to "pause" at, in your case [1, 2, 3, 4, 5] which are sorted numerically. You will then keep track of the current index by checking elapsed >= secs and if it succedds you will increment it by one. Here's a glance

import time

def tick(tocks: list):
    """Tocks is a list of the time intervals which you want to be
       notified at when are reached, all of them are going to run in parallel.
    """
    tocks = sorted(tocks) 
    current = 0  # we are at index 0 which is the lowest interval

    start = time.time()
    while current < len(tocks): # while we have not reached the last interval
        end = time.time()
        elapsed = end - start
        if elapsed >= tocks[current]: # if the current interval has passed check for the next 
            print(f"Tock: {tocks[current]}")
            current += 1

This function can then be called like this

tick([1, 2, 3, 4, 5])

This will print 1 to 5 seconds at the same time. Here is the output

Tock: 1 # at 1 sec
Tock: 2 # at 2 sec
Tock: 3 # at 3 sec
Tock: 4 # .....
Tock: 5

You can imagine that this may have some minor flaws if you choose really close numbers like [0.5, 0.50001, 0.50002] and because the difference is so small 0.0001 seconds may not actually pass.

You could also try multithreading as has been noted, but it will be a very CPU-intensive (imagine wanting to count to 100 and you have to open 100 threads) task for something very simple.

Countour-Integral
  • 1,138
  • 2
  • 7
  • 21
  • Thank you!, this works for waiting but I need something that also runs in the background for example running this function as: `tick([1, 2, 3, 4, 5])` but being able use an `input()` anywhere while still keeping the count accurate so python isn't waiting for an input before printing the tocks. – RazerDemon Jan 15 '21 at 00:39
  • @RazerDemon Is printing the only thing you want to do, or do you want to be able to access the current time interval in `input()`? If you only want to print you can just create a new thread just for the input, in the other case (you want to be able to access) things are difficut and not cross platform as you can take a look [here](https://stackoverflow.com/questions/2408560/python-nonblocking-console-input) or [here](https://stackoverflow.com/questions/21791621/taking-input-from-sys-stdin-non-blocking). – Countour-Integral Jan 15 '21 at 00:46
  • The printing is only to see if the values are getting updated at the right times. I want to use this as a timer for updating values that is resettable but also updates in the background, not disturbing the output of the rest of the code. Like making a cooldown for an ability in a video game. – RazerDemon Jan 15 '21 at 01:01