Display a countdown for the python sleep function
Asked Answered
I

12

31

I am using time.sleep(10) in my program. Can display the countdown in the shell when I run my program?

>>>run_my_program()
tasks done, now sleeping for 10 seconds

and then I want it to do 10,9,8,7....

is this possible?

Indium answered 20/6, 2013 at 17:33 Comment(2)
Thank you for all the wonderful answers.Indium
related: countdown using using Tkinter, or Gtk, or Twisted or Asyncio event loopsWeiland
B
42

you could always do

#do some stuff
print 'tasks done, now sleeping for 10 seconds'
for i in xrange(10,0,-1):
    time.sleep(1)
    print i

This snippet has the slightly annoying feature that each number gets printed out on a newline. To avoid this, you can

import sys
import time
for i in xrange(10,0,-1):
    sys.stdout.write(str(i)+' ')
    sys.stdout.flush()
    time.sleep(1)
Backstretch answered 20/6, 2013 at 17:36 Comment(3)
thanks, this is great. you have just a small mistake which I fixed. time.sleep(i) should be time.sleep(1)Indium
Yes, indeed, it is fixed for the answer.Backstretch
If you're getting NameError: name 'xrange' is not defined use range instead. It was renamed in Python 3.Cognate
G
34

This is the best way to display a timer in the console for Python 3.x:

import time
import sys

for remaining in range(10, 0, -1):
    sys.stdout.write("\r")
    sys.stdout.write("{:2d} seconds remaining.".format(remaining))
    sys.stdout.flush()
    time.sleep(1)

sys.stdout.write("\rComplete!            \n")

This writes over the previous line on each cycle.

Generalist answered 24/2, 2017 at 1:57 Comment(0)
R
19

A simple solution that clears the last number from the console:

import time

for i in range(10,0,-1):
    print(f"{i}", end="\r", flush=True)
    time.sleep(1)

By default, the print function sets end="\n" which means subsequent calls to print will be printed on a new line. You can change this to end="\r" to replace the output after each call. (How does carriage return "\r" work in python).

Here f"{i}" is for printing single digit only. You can modify it based on number of digits. e.g. Here it will work for two digits by just adding one space as a postfix- f"{i} "

Also, using flush means you don't have to worry about buffering issues. (What does print()'s flush do?)

This is how it looks:

countdown

Rina answered 4/4, 2021 at 11:46 Comment(4)
This great, however if you input a large number, say 1200, it will end up printing e.g. 8790 instead of 0879 or 879, any way to fix this?Aubin
Oris, Updated the answer as per your comment.Trask
Change the "print(f("{i}..." for this line print("{:2d}".format(i), end="\r", flush=True) Or I will add an edit below this answerSublunary
An alternative is to print another line prior to clear it, such as print('\r', ' '*100, end='')Inalienable
A
8

You can do a countdown function like:

import sys
import time

def countdown(t, step=1, msg='sleeping'):  # in seconds
    pad_str = ' ' * len('%d' % step)
    for i in range(t, 0, -step):
        print '%s for the next %d seconds %s\r' % (msg, i, pad_str),
        sys.stdout.flush()
        time.sleep(step)
    print 'Done %s for %d seconds!  %s' % (msg, t, pad_str)

The carriage return \r and the comma , will keep the print in the same line (avoiding one line for each countdown value)

As the number of seconds decreases, the pad_str will ensure the last line is overwritten with spaces instead of leaving the last character(s) behind as the output shortens.

The final print overwrites the last status message with a done message and increments the output line, so there is evidence of the delay.

Ancalin answered 20/6, 2013 at 17:37 Comment(1)
To prevent a new line inserted every second in the countdown, the statement print '%s for the next %d seconds %s\r' % (msg, i, pad_str), should be changed to sys.stdout.write( '%s for the next %d seconds %s\r' % (msg, i, pad_str),).Orthogenetic
N
2

Here's one I did:

import time
a = input("How long is the countdown?")
while a != 0:
    print a
    time.sleep(1)
    a = a-1

At the end if you and an else you can put an alarm or whatever.

Notepaper answered 11/8, 2013 at 18:51 Comment(0)
W
2

time.sleep() may return earlier if the sleep is interrupted by a signal or later (depends on the scheduling of other processes/threads by OS/the interpreter).

To improve accuracy over multiple iterations, to avoid drift for large number of iterations, the countdown may be locked with the clock:

#!/usr/bin/env python
import sys
import time

for i in reversed(range(1, 1001)):
    time.sleep(1 - time.time() % 1) # sleep until a whole second boundary
    sys.stderr.write('\r%4d' % i)
Weiland answered 6/2, 2015 at 16:8 Comment(0)
D
2

This is something that I've learned at one of my first python lessons, we played with ["/","-","|","\","|"] but the principle is the same:

import time

for i in reversed(range(0, 10)):
    time.sleep(1)
    print "%s\r" %i,
Donaugh answered 20/6, 2015 at 22:50 Comment(0)
G
2

Another easy way, without reinventing the wheel, is to use tqdm, which automatically displays a progress bar:

from time import sleep
from tqdm import tqdm

for _ in tqdm(range(10)):
    sleep(1)

Optionally, you can then modify the display of the loading bar as you wish.

Gebhart answered 11/10, 2021 at 9:41 Comment(0)
K
1

Sure, just write a loop that prints 10 minus the iteration counter, then have it sleep 1 second each iteration and run for 10 iterations. Or, to be even more flexible:

def printer(v):
    print v
def countdown_timer(duration, step=1, output_function=printer,
                    prompt='Waiting {duration} seconds.'):
    output_function(prompt.format(duration=duration))
    for i in xrange(duration/step):
        output_function(duration - step * i)
Kwangtung answered 20/6, 2013 at 17:37 Comment(0)
P
0

This one is subsecond precise:

    print()
    _k = 0.5  # ensure k != _k first time round (as k will be integer)
    print('Starting in ')
    while _k > 0:
        k = round(event_timestamp - time())
        if k != _k:
            print(f'\r{k} ', end='', flush=True)
            _k = k
        sleep(0.1)

    print('boom')

Notice the trailing space in f'\r{k} '. So if we go from 100 to 99 or 10 to 9 it clears the second digit.

Also it doesn't require import sys.

sleep(0.0003) if you want millisecond precision.

Plonk answered 1/6, 2021 at 12:42 Comment(0)
M
0

if you don't limit yourself to sleep, then (courtesy automatetheboringstuff), pyautogui has a nifty countdown function:

import pyautogui
print('Starting in ', end=''); pyautogui.countdown(3)
Malediction answered 6/7, 2021 at 0:53 Comment(0)
D
0

may be this will help

    import turtle
    for i in range(10):
        t2 = turtle.Turtle()
        t2.hideturtle()
        t2.penup()
        t2.goto(0,0)
        t2.write(i,font=("Arial", 16, "normal"))
        i-=1
        sleep(1)
        t2.clear()
Donell answered 4/2, 2023 at 13:58 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Reflect

© 2022 - 2025 — McMap. All rights reserved.