Home > python > Countdown in command line

Countdown in command line

I have a console application that runs in an eternal loop. It does something then it sleeps for 5 minutes. How to do this pause in a nice way?

(1) time.sleep(300)

The first idea is to put it to sleep for 5 minutes. It does the job but when I check the output of the script, I have no idea when it continues. So it’s not very informative.

(2) print a dot each second

Another way is to print a dot each second. If you use sys.stdout.write('.'), then don’t forget to set the output unbuffered. It’s a bit better but still not perfect.

(3) countdown

The nicest way may be a countdown that goes from 300 down to 0. Now, you don’t want to print each number in a new line, do you? How to keep the countdown in the same line?

#!/usr/bin/python2.7 -u
# -u switch: unbuffered output

def wait(sec):
    while sec > 0:
        sys.stdout.write(str(sec) + '     \r')
        sec -= 1
        time.sleep(1)

The trick is the ‘\r‘, which means “carriage return”. That is: print the number, clear with some spaces, then jump back to the beginning of the line.

Nice, but… How to get rid of the cursor? You can switch it off/on in Linux easily. Here is my complete solution:

#!/usr/bin/python2.7 -u

import os
import sys
from time import sleep

def wait(sec):
    while sec > 0:
        sys.stdout.write(str(sec) + '     \r')
        sec -= 1
        sleep(1)
        
def main():
    os.system('setterm -cursor off')
    try:
        while True:
            # an external command that I call regularly
            os.system('./proxies.py')
            wait(300)
    except KeyboardInterrupt:
        print
    finally:
        os.system('setterm -cursor on')

############################################ 

if __name__ == "__main__":
    main()

The finally part makes sure that the cursor will be switched back on, even if the script is interrupted with CTRL+C for instance.

The same idea in a more elegant way:

class CursorOff(object):
    def __enter__(self):
        os.system('setterm -cursor off')
        
    def __exit__(self, *args):
        os.system('setterm -cursor on')

def wait(sec):
    while sec > 0:
        sys.stdout.write(str(sec) + '     \r')
        sec -= 1
        try:
            sleep(1)
        except KeyboardInterrupt:
            print
            return

with CursorOff():
    wait(3)

I put it in a module that you can find in my jabbapylib library, here.

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: