Ogen
Ogen

Reputation: 6709

Python command line print on the same lines

There are many questions relating to printing on the same line but there aren't any for printing multiple lines on the same line within the terminal.

For example:

ogeno@OH-ogeno-MBP:~|⇒ python my_script.py
Process 1: 5%
Process 2: 14%
Process 3: 55%

I want the progress of these processes to update on the same line rather than printing over and over again. I have looked at other questions that say to use the return carriage character \r and sys.stdout.flush() but it doesn't seem to change the caret to go up a line, just to the end of the current line.

EDIT: My question is different because it's to do with printing MULTIPLE lines on the same lines in the terminal. It's easy if it's just one line.

Upvotes: 2

Views: 3120

Answers (3)

user2390182
user2390182

Reputation: 73450

One approach is to use the ANSI escape-code "\033[F" for going to the beginning of the previous line. The following worked well in all my terminals, just writing to the next two lines from the current terminal position:

import time
import sys

progress_1 = 'Process 1: {}%'
progress_2 = 'Process 2: {}%'
print
print

for i in range(100):
    sys.stdout.write('\033[F')
    sys.stdout.write('\033[F')
    print(progress_1.format(i))
    print(progress_2.format(i))
    time.sleep(0.02)

Upvotes: 1

Hassan Mehmood
Hassan Mehmood

Reputation: 1402

This can easily be done by using backspace. Following is the sample code that will print the percentage on the same line.

import time
print "Work in progress(0%%)", # Python 2 print without newline
for work_done in range(10):
    print "\b\b\b\b\b%2d%%)" % work_done, # Backspace then overwrite
    time.sleep(1)

Upvotes: 1

binu.py
binu.py

Reputation: 1216

for python 2.7 you can use,

print 2%, 3% # Using comma will print it in same line

for python 3.x

print('2%', end=" ")

Or you can use sys.stdout.write for doing it with sys.stdout.flush() Please check my below code, I have created a demo progress bar.

"""ProgressBar Module."""

import sys
import time


class ProgressBar(object):
    """Main class for the ProgressBa."""

    DEFAULT_BAR_LENGTH = float(30)

    def __init__(self, start=0, step=1):
        """Init for the class."""
        self.end = ProgressBar.DEFAULT_BAR_LENGTH
        self.start = start
        self.step = step
        self.total = self.end - self.start
        self.counts = self.total / self.step
        self._barLength = ProgressBar.DEFAULT_BAR_LENGTH

        self.set_level(self.start)
        self._plotted = False

    def set_level_old(self, level, initial=False):
        """Setting Level."""
        self._level = level
        if level < self.start:
            self._level = self.start
        if level > self.end:
            self._level = self.end

        self._ratio = float(
            self._level - self.start) / float(self.end - self.start)
        self._levelChars = int(self._ratio * self._barLength)

    def set_level(self, level, initial=False):
        """Setting Level."""
        self._level = level
        if level < self.start:
            self._level = self.start
        if level > self.end:
            self._level = self.end

        self._ratio = float(self._level) / float(self._barLength)
        self._levelChars = int(self._ratio * self._barLength) * self.step

    def plot_progress(self):
        """Plotting the bar."""
        sys.stdout.write("\r  %3i%%  |%s%s|" % (
            int(self._ratio * self.step * 100.0),
            u'\u2588' * int(self._levelChars),
            ' ' * int(self._barLength - self._levelChars),
        ))
        sys.stdout.flush()
        self._plotted = True

    def set_and_plot(self, level):
        """Call the plot."""
        old_chars = self._levelChars
        self.set_level(level)
        if (not self._plotted) or (old_chars != self._levelChars):
            self.plot_progress()

    def __del__(self):
        """Del for the class."""
        sys.stdout.write("\n")

if __name__ == "__main__":

    pb = ProgressBar(0, 1)

    curProgress = 0
    pb.plot_progress()
    while curProgress <= pb.counts:
        pb.set_and_plot(curProgress)
        curProgress += 1
        time.sleep(0.1)

    del pb

Upvotes: 0

Related Questions