4

I wrote this simple function "processing_flush" in order to print a sequence of points (given by index) to test if my software is processing my data and eventually the speed. The total size of my data is unknown.

    import sys
    import time

    def processing_flush(n, index=5):
        sys.stdout.write("\rProcessing %s" % ((n % index)* "."))
        sys.stdout.flush()

    for n in xrange(20):
        processing_flush(n, index=5)
        time.sleep(1)

The problem that i cannot fix is when all points are printed the first time (ex: Processing .... if index is equal to 5) the cursor doesn't start from zero.

0

1 Answer 1

6

Before you overwrite the same line again you need to clear at least the positions where the dots are with spaces.

def processing_flush(n, index=5):
    sys.stdout.write("\rProcessing %s" % (index * " "))
    sys.stdout.write("\rProcessing %s" % ((n % index)* "."))
    sys.stdout.flush()

The code above may lead to some brief flicker. In your specific case it is sufficient to clear the line when n % index becomes 0:

def processing_flush(n, index=5):
    if n % index == 0:
        sys.stdout.write("\rProcessing %s" % (index * " "))
    sys.stdout.write("\rProcessing %s" % ((n % index)* "."))
    sys.stdout.flush()

Or even better always write index-1 characters:

def processing_flush(n, index=5):
    sys.stdout.write("\rProcessing %s%s" % ((n % index)* ".", (index - 1 - (n % index))* " "))
    sys.stdout.flush()

Edit 1: Or if you prefer to have the cursor always after the last dot:

def processing_flush(n, index=5):
    sys.stdout.write("\rProcessing %s%s" % ((n % index)* ".", (index - 1 - (n % index))* " "))
    sys.stdout.write("\rProcessing %s" % ((n % index)* "."))
    sys.stdout.flush()

Edit 2: Or if you prefer to have the cursor always at the beginning of the line:

def processing_flush(n, index=5):
    sys.stdout.write("Processing %s%s\r" % ((n % index)* ".", (index - 1 - (n % index))* " "))
    sys.stdout.flush()

The reason is that your shell remembers the remaining characters of the previous line if you overwrite just the first part of it.

Sign up to request clarification or add additional context in comments.

9 Comments

Wow it was so easy!!. Thanks Johannes, i had spent several hours to surf in google in order to find a solution!!!
@Gianni: Combine 3 and 2: Copy the second-last line from solution 2 into solution 3 before the sys.stdout.flush().
@DanielFrey yes the 2+3 it's the most elegant solution from my point of view
Ah yes, I see, that is good. What you can also do is append a \rat the end of the strings. This will move the cursor always to the beginning of the line. But this is a matter of preference. This also has the advantage that when you print the next line you can overwrite your progress bar. But this is again a matter of preference I guess. I updated the answer according to Daniels suggestion.
No, this was not a silly question at all! :-) We have been sitting there scratching our heads. And I still often do when I see what a terminal can do (or can not do).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.