6

For my current project, there are some pieces of code that are slow and which I can't make faster. To get some feedback how much was done / has to be done, I've created a progress snippet which you can see below.

When you look at the last line

sys.stdout.write("\r100%" + " "*80 + "\n")

I use " "*80 to override eventually remaining characters. Is there a better way to clear the line?

(If you find the error in the calculation of the remaining time, I'd also be happy. But that's the question.)

Progress snippet

#!/usr/bin/env python

import time
import sys
import datetime


def some_slow_function():
    start_time = time.time()
    totalwork = 100
    for i in range(totalwork):
        # The slow part
        time.sleep(0.05)
        if i > 0:
            # Show how much work was done / how much work is remaining
            percentage_done = float(i)/totalwork
            current_running_time = time.time() - start_time
            remaining_seconds = current_running_time / percentage_done
            tmp = datetime.timedelta(seconds=remaining_seconds)
            sys.stdout.write("\r%0.2f%% (%s remaining)   " %
                             (percentage_done*100, str(tmp)))
            sys.stdout.flush()
    sys.stdout.write("\r100%" + " "*80 + "\n")
    sys.stdout.flush()

if __name__ == '__main__':
    some_slow_function()

Consoles

I use ZSH most of the time, sometimes bash (and I am always on a Linux system)

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958

2 Answers2

12

Try using the ANSI/vt100 "erase to end of line" escape sequence:

sys.stdout.write("\r100%\033[K\n")

Demonstration:

for i in range(4):
    sys.stdout.write("\r" + ("."*i*10))
    sys.stdout.flush()
    if i == 3:
        sys.stdout.write("\rDone\033[K\n")
    time.sleep(1.5)

Reference: https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences

Mr. DOS
  • 379
  • 2
  • 13
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
0

This is what I use

from msvcrt import putch, getch

def putvalue(value):
   for c in str(value):
      putch(c)

def overwrite(value):
   """ Used to overwrite the current line in the command prompt,
   useful when displaying percent or progress """
   putvalue('\r'+str(value))

from time import sleep


for x in xrange(101):
   overwrite("Testing Overwrite.........%s%% complete" % x)
   sleep(.05)
user2682863
  • 3,097
  • 1
  • 24
  • 38