繁体   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