簡體   English   中英

如何輸入時間並讓計時器倒計時? Python

[英]How can I input a time and have the timer count down? Python

我正在嘗試運行一個while循環,這樣我就可以在計時器仍在倒計時時運行代碼。我還想在計時器倒計時時看到它。 我試圖在堆棧溢出時找到類似的東西,但無法得到我正在尋找的結果。

Python

print("Input minutes and seconds")
min = int(input("Minutes: "))
sec = int(input("Seconds: "))

while min & sec > 0:
    # do some code
    # I want the program to count down from whatever I input
    print("")

您應該在不同的線程上運行計時器。 如果您不需要計時器來影響正在運行的主代碼,這應該可以工作:

import threading
import time

def timer_function(seconds):
    '''Countdown from number of seconds given'''
    for t in range(seconds, -1, -1):
        time.sleep(1)
        print(t)


if __name__ == "__main__":
    print("Input minutes and seconds")
    min = int(input("Minutes: "))
    sec = int(input("Seconds: "))

    x = threading.Thread(target=timer_function, args=(min * 60 + sec,))
    x.start()

    # Run some other code in parallel with the timer

    x.join() # will wait for the timer function to finish
    print('All done')

如果您需要計時器來停止主線程(在主函數上運行的代碼),那么您需要通過來自計時器線程的變量發送一些信號。 如果您想查找它,可能有一些庫可以更好地處理線程超時:)

獲得非常精確的超時時間有點麻煩,因為如果不仔細編寫,報告時間的操作會影響時間本身。

像這樣的事情通常最好用兩個線程並行完成

使線程“守護線程”允許您通過退出程序來結束它們(否則程序將等待它們被.join()編輯)

您可以依靠threading.Event()清楚地與線程通信並提供.wait()方法,該方法將等待給定的超時或在事件.is_set()時立即結束

import threading 
import time

def function_to_call():  # replace me with your function
    time.sleep(1000)

def timer_fn(timeout, event, delay=5):  # 5 seconds between reports
    time_end = time.time() + timeout
    while True and not event.is_set():
        time_remaining = int(time_end - time.time())
        if time_remaining <= 0:
            return
        print(
f"{int(time_remaining)}s remaining")
        event.wait((min(delay, time_remaining)))  # wait for event

timeout = int(input("minutes: ") or 0) * 60 + int(input("seconds: ") or 0)

E = threading.Event()  # Event to kill t2
# making t1 a daemon lets it not prevent shutdown
t1 = threading.Thread(target=function_to_call, daemon=True)
t2 = threading.Thread(target=timer_fn, args=(timeout, E), daemon=True)

# begin both threads
t1.start()
t2.start()
# wait for t1 to exit (but not t2)
t1.join(timeout=timeout)
# t1 may join faster by ending, otherwise reach here after timeout
E.set()  # set the Event to quickly end t2 (timeout or t1 returned)
t2.join()  # not technically necessary, but cleans up t2

# program quits and t1 is killed if it's still running

注意,時序顯示其實和線程結束是分開的,提前結束function在這里通過停止程序來完成。 如果程序沒有停止,function 將繼續運行!

如果需要更高級的任務控制,請考慮

  • 修改您的可調用 function 以反復檢查另一個threading.Event 。事件貫穿其中以查看時間是否到了(還)
  • 使用multiprocessing ,這比threading更有特色,雖然它可能需要將 memory 復制到新進程中,如果你有大量的可能會很慢
  • 使用subprocess ,創建一個腳本只是為了定時結束(在這里你可以用一個簡單的.kill()殺死子進程或在創建它時設置timeout=參數!(盡管你會再次發現復制效率低下/流式輸入進出新流程)
  • 使用os.fork()和 [ os.kill()](https://docs.python.org/3/library/os.html#os.kill) to split your process (advanced, but usually much more efficient than多處理`由於 memory 是(或者更確切地說是不)復制)
  • 如果您的 function 可以設為異步,這允許多個任務在同一個命名空間中進行協作,類似於threading ,但以更友好的方式(盡管它的行為方式與給定的其他技術根本不同,如果您有許多不依賴本地資源的任務,例如網絡服務器或數據庫)

盡管在根本上有所不同,但您可能會發現將您的任務設計為可迭代的工作集合(可能在列表中)並考慮使用像tqdm這樣的庫來報告其狀態時會獲得更多或更多的好處

理想情況下,您應該使用線程並生成一個守護進程來跟蹤,但這對您的情況來說可能是多余的。 我做了一個更簡單的實現,希望可以理解,否則請詢問,我會改進評論/解釋:

import time

set_time = int(input('For how many seconds do you want to run this?'))
start_time = time.time()  # lets get the current time
inner_time = time.time()  # Seperate vars so we don't overwrite the main loop 
count = 0 #To keep track of how many seconds we've been going

while (time.time() - start_time) < set_time: #Lets run this until we've reached our time
        if(time.time() - inner_time) >= 1: #If 1 sec has passed
            inner_time = time.time() #Reset time
            count += 1 #Increase second by 1  
            print("Code has been running for "+str(count)+" seconds") #Inform the user

        #Do something here...
            

print(str(set_time)+" seconds have now elapsed") #Done and dusted

這是 output:

For how long do you want to run this?5
Code has been running for 1 seconds
Code has been running for 2 seconds
Code has been running for 3 seconds
Code has been running for 4 seconds
5 seconds have now elapsed

嘗試這個,

代碼:

import time

print("Input minutes and seconds")
min = int(input("Minutes: "))
sec = int(input("Seconds: "))
t = min*60 + sec

while t : 
    mins, secs = divmod(t, 60)
    timer = '{:02d}:{:02d}'.format(mins, secs)
    print(timer, end="\r")
    time.sleep(1)
    t -= 1

print('Timer ended !!')

Output:

Input minutes and seconds
Minutes: 1
Seconds: 5
01:05
01:04
01:03
01:02
01:01
01:00
00:59
00:58
.
.
.
00:01
Timer ended !!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM