简体   繁体   English

如何输入时间并让计时器倒计时? Python

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

I am trying to run a while loop so I can run code while the timer is still counting down.I also want to see the timer as it counts down.我正在尝试运行一个while循环,这样我就可以在计时器仍在倒计时时运行代码。我还想在计时器倒计时时看到它。 I have tried to find something similar on stack overflow, but haven't been able to get the result I'm looking for.我试图在堆栈溢出时找到类似的东西,但无法得到我正在寻找的结果。

Python 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("")

You should run your timer on a different thread.您应该在不同的线程上运行计时器。 If you don't need the timer to affect the main code being run this should work:如果您不需要计时器来影响正在运行的主代码,这应该可以工作:

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')

If you need the timer to stop the main thread (the code being run on the main function) then you need send some signal through a variable from the timer thread.如果您需要计时器来停止主线程(在主函数上运行的代码),那么您需要通过来自计时器线程的变量发送一些信号。 There might be some libraries that handle thread timeouts better if you would like to look it up:)如果您想查找它,可能有一些库可以更好地处理线程超时:)

Getting very precise timeout timing is somewhat troublesome, as the operation of reporting on the timing can affect the timing itself if not carefully written.获得非常精确的超时时间有点麻烦,因为如果不仔细编写,报告时间的操作会影响时间本身。

Something like this is often best accomplished with two threads in parallel像这样的事情通常最好用两个线程并行完成

Making the threads "daemon threads" allows you to end them by quitting the program (otherwise the program will wait for them to be .join() ed)使线程“守护线程”允许您通过退出程序来结束它们(否则程序将等待它们被.join()编辑)

You can rely on threading.Event() to clearly communicate into a thread and provide a .wait() method, which will either wait for a given timeout or immediately end when the event .is_set()您可以依靠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

Note that the timing display is actually separate from the thread ending, and ending the function early is done here by stopping the program.注意,时序显示其实和线程结束是分开的,提前结束function在这里通过停止程序来完成。 The function will continue to run if the program is not stopped!如果程序没有停止,function 将继续运行!

If more advanced task control is needed, consider如果需要更高级的任务控制,请考虑

  • modifying your callable function to repeatedly check another threading.Event throughout it to see if it's time is up (yet)修改您的可调用 function 以反复检查另一个threading.Event 。事件贯穿其中以查看时间是否到了(还)
  • use multiprocessing , which is much more featureful than threading , though it may need to copy memory into the new process, which can be slow if you have a tremendous amount使用multiprocessing ,这比threading更有特色,虽然它可能需要将 memory 复制到新进程中,如果你有大量的可能会很慢
  • use subprocess , creating a script just for the purpose of a timed end (here you can kill the subprocess with a simple .kill() or setting a timeout= argument when creating it! (though again you'll find some inefficiency in copying/streaming input into and out of the new process)使用subprocess ,创建一个脚本只是为了定时结束(在这里你可以用一个简单的.kill()杀死子进程或在创建它时设置timeout=参数!(尽管你会再次发现复制效率低下/流式输入进出新流程)
  • use os.fork() and [ os.kill()](https://docs.python.org/3/library/os.html#os.kill) to split your process (advanced, but usually much more efficient than multiprocessing` due to how memory is (or rather is not) copied)使用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 是(或者更确切地说是不)复制)
  • if your function can be made asynchronous , which allows multiple tasks to collaborate in the same namespace similar to threading , but in a more friendly way (though how this behaves is fundamentally different from the other techniques given, it can be very efficient if you have many tasks which don't rely on local resources, such as a webserver or database)如果您的 function 可以设为异步,这允许多个任务在同一个命名空间中进行协作,类似于threading ,但以更友好的方式(尽管它的行为方式与给定的其他技术根本不同,如果您有许多不依赖本地资源的任务,例如网络服务器或数据库)

Though further fundamentally different, you may find further or more benefit in designing your task to be a collection of work to iterate over (maybe in a list) and consider a library like tqdm to report on its status尽管在根本上有所不同,但您可能会发现将您的任务设计为可迭代的工作集合(可能在列表中)并考虑使用像tqdm这样的库来报告其状态时会获得更多或更多的好处

You should ideally use threads and spawn a daemon to keep track, but that might be overkill for your case.理想情况下,您应该使用线程并生成一个守护进程来跟踪,但这对您的情况来说可能是多余的。 I've made a more simple implementation which is hopefully understandable, otherwise please ask and I'll improve the comments/explanation:我做了一个更简单的实现,希望可以理解,否则请询问,我会改进评论/解释:

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

This is the output:这是 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

Try this,尝试这个,

Code:代码:

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: 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