Reputation: 6709
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
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
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
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