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?

user1681664
  • 1,771
  • 8
  • 28
  • 53

12 Answers12

40

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)
David Resnick
  • 4,891
  • 5
  • 38
  • 42
aestrivex
  • 5,170
  • 2
  • 27
  • 44
29

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.

Barkles
  • 703
  • 9
  • 12
17

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

IRSHAD
  • 2,855
  • 30
  • 39
zcahgg1
  • 375
  • 3
  • 8
  • 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? – Oris May 02 '22 at 20:41
  • Oris, Updated the answer as per your comment. – IRSHAD May 26 '22 at 14:02
  • Change the "print(f("{i}..." for this line `print("{:2d}".format(i), end="\r", flush=True)` Or I will add an edit below this answer – Corina Roca Jun 05 '23 at 12:42
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.

Maruf
  • 792
  • 12
  • 36
Saullo G. P. Castro
  • 56,802
  • 26
  • 179
  • 234
  • 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),)`. – Jack Fleeting Feb 24 '19 at 23:47
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.

Community
  • 1
  • 1
Silas
  • 76
  • 6
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)
jfs
  • 399,953
  • 195
  • 994
  • 1,670
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,
Azur
  • 53
  • 4
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)
Silas Ray
  • 25,682
  • 5
  • 48
  • 63
1

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.

Nick
  • 153
  • 7
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.

P i
  • 29,020
  • 36
  • 159
  • 267
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)
JB-007
  • 2,156
  • 1
  • 6
  • 22
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()
  • 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](/help/how-to-answer). – Community Feb 05 '23 at 21:36