How to use \r to print on same line?

65,942

Solution 1

Put the \r at the beginning or end of your printed string, e.g. '\rthis string will start at the beginning of the line'. or 'the next string will start at the beginning of the line\r'. Conceptually, \r moves the cursor to the beginning of the line and then keeps outputting characters as normal.

You also need to tell print not to automatically put a newline character at the end of the string. In python3, you can use end="" as in this previous stackoverflow answer.

Alternatively, instead of using print you can do import sys and sys.stdout.write('whatever'), which sends only the exact characters to stdout without an implicit newline. You'll probably also want to use sys.stdout.flush(), without which it will store characters in a buffer rather than printing them immediately.

Solution 2

Add an , end="\r" to you print function. Also make sure your printed data has enough space to overwrite the previous printed data or be of the same length since just moving to the same line would not automatically clear the previous contents.

Solution 3

You can use sys.stdout.write:

import time
import sys

def timer(t=5):
    t0 = time.time()
    now = t0
    while now-t0 < t:
        now = time.time()
        timestr = '\r%%%i\t' %(100*(now-t0)/t)
        sys.stdout.write(timestr)
        sys.stdout.flush()
        time.sleep(0.1)
Share:
65,942

Related videos on Youtube

Santosh Kumar
Author by

Santosh Kumar

Fullstack Developer at Method Studios. I love developing the backend. You can find me on Twitter.

Updated on August 12, 2022

Comments

  • Santosh Kumar
    Santosh Kumar over 1 year

    I have made a downloader:

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    
    from __future__ import print_function, division, absolute_import, unicode_literals
    import os
    import argparse
    try:
        from urllib2 import urlopen
    except ImportError:
        from urllib.request import urlopen
    
    # {{ Argument parser
    parser = argparse.ArgumentParser(
        prog='downloader',
        description='a featureful downloader'
    )
    
    parser.add_argument(
        '-o',
        dest='outputfile'
    )
    
    parser.add_argument(
        '-r',
        dest='remotefile'
    )
    
    downloader = parser.parse_args()
    # }}
    
    # {{ default local filename
    if downloader.outputfile:
        default_output_file = downloader.outputfile
    else:
        default_output_file = os.path.split(downloader.remotefile)[-1]
    # }}
    
    u = urlopen(downloader.remotefile)
    meta = u.info()
    file_size  = int(dict(meta.items())['Content-Length'])
    print("Downloading: %s Bytes: %s" % (default_output_file, file_size))
    
    with open(default_output_file, 'wb') as f:
        file_size_dl = 0
        block_sz = 8192
        while True:
            buffer = u.read(block_sz)
            if not buffer:
                break
    
            file_size_dl += len(buffer)
            f.write(buffer)
            status = r"%10d  [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
            status = status + chr(8)*(len(status)+1)
            print(status)
    

    A sample run of this script would be:

    python3 downloader.py -o ubuntu.iso -r http://releases.ubuntu.com/13.04/ubuntu-13.04-desktop-i386.iso
    

    And a sample output will be:

    Downloading: ubuntu.iso Bytes: 832569344
          8192  [0.00%]
         16384  [0.00%]
         24576  [0.00%]
         32768  [0.00%]
         40960  [0.00%]
         49152  [0.01%]
         57344  [0.01%]
         65536  [0.01%]
         73728  [0.01%]
         81920  [0.01%]
         90112  [0.01%]
         98304  [0.01%]
        106496  [0.01%]
        114688  [0.01%]
        122880  [0.01%]
        131072  [0.02%]
        139264  [0.02%]
        147456  [0.02%]
        155648  [0.02%]
        163840  [0.02%]
    

    Note that as the loop goes the output is printed on a separate lines. I know I can use \r (carriage return) to do that. But I have confusion where and how to use that.

  • Jonathan Hartley
    Jonathan Hartley almost 8 years
    Cute idea to use 'end', but I prefer to print the '\r' right before printing my value, not after. That way, anything else that gets printed (e.g. a traceback) doesn't overwrite the last printed value.

Related