Асинхронный таймер на питоне

Короче, хочу сделать таймер, который при клике или вводе текста в консоль пишет сколько осталось, и при этом основной процесс не сворачивается. Сколько не пытался, получается только последовательно запускать -проверку консоли и таймер.

import datetime
from time import sleep


# введите время таймера
timer=int(input("How minutes it would take? "))*60
timerFinish=int(datetime.datetime.now().timestamp())+timer


def WhatLeft(timerFinish):
    if tellSth != None:
        left=timerFinish-int(datetime.datetime.now().timestamp())
        print("Left %s min, %s sec " % (left//60,left%60))
        tellSth=input('Whrite sth to see how much left: ')

def Pomodorro(timer):
    sleep(timer)
    print(f'You timer for {timer/60} has ended')
    

Pomodorro(timer)

Есть идеи как это сделать? Обратите внимание, таймер должен дотикать САМ, без командной строки


Ответы (2 шт):

Автор решения: RuslanZanevskiy

Думаю такая реализация подойдет вам. Она не приостанавливает работу программы в отличии от sleep(). И можно создавать много таймеров одновеменно.

import time

class MyTimer:
    def __init__(self, time_to_wait):
        self.time_to_wait = time_to_wait
        self.time_to_stop = 0
    
    def start(self):
        self.time_to_stop = round(time.time()) + self.time_to_wait

    def left(self):
        left = self.time_to_stop - round(time.time())
        return left if left > 0 else 0

def main():
    seconds_to_wait = int(input('How long it would take(in minutes)? ')) * 60
    timer = MyTimer(seconds_to_wait)
    timer.start()

    while 1:
        cmd = input('Command: ')
        if cmd == 'left':
            print(timer.left(), 'seconds')
        else:
            # do something else
            pass

if __name__ == '__main__':
    main()
→ Ссылка
Автор решения: Булат Мустафин

Написал рабочую версию этого таймера.

import datetime
from time import sleep
from threading import Timer
# введите время таймера
timer=int(input("Скоолько минут это займет? "))*60
timerFinish=int(datetime.datetime.now().timestamp())+timer
left=timerFinish-int(datetime.datetime.now().timestamp())

def timeLeft(left):
    answer = input("Если хотите узнать оставшееся время, пишите :")
    if answer:
        print (f"У вас осталось {left} секунд")

def Pomodorro(timer):
    
    left=timerFinish-int(datetime.datetime.now().timestamp())
    
    
    while left>0:
        
        
        
        left=timerFinish-int(datetime.datetime.now().timestamp())
        t = Timer(left, timeLeft(left))
        t.start()
        
        t.cancel()
            
        left=timerFinish-int(datetime.datetime.now().timestamp())
        
    print(f'You timer for {int(timer/60)} has ended')
    
Pomodorro(timer)
→ Ссылка