Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3 Print Update on multiple lines

Tags:

python

Is it possible to print and update more than one line? This works for one line:

print ("Orders: " + str(OrderCount) + " Operations: " + str(OperationCount), end="\r")

and get this: (Of course the numbers update because its in a loop)

Orders: 25 Operations: 300

I have tried this:

print ("Orders: " + str(OrderCount) + "\rOperations: " + str(OperationCount), end="\r\r")

and get this: (The number does update correctly)

Operations: 300

Looking for two lines that are updated like:

Orders: 25
Operations: 300

and not:

Orders: 23
Operations: 298

Orders: 24
Operations: 299

Orders: 25
Operations: 300
like image 526
Mattman85208 Avatar asked Sep 12 '16 16:09

Mattman85208


1 Answers

\r is a carriage return, where the cursor moves to the start of the line (column 0). From there, writing more text will overwrite what was written before, so you end up only with the last line (which is long enough to overwrite everything you've written before).

You want \n, a newline, which moves to the next line (and starts at column 0 again):

print("Orders: " + str(OrderCount) + "\nOperations: " + str(OperationCount), end="\n\n")

Rather than use str() and + concatenation, consider using string templating with str.format():

print("Orders: {}\nOperations: {}\n".format(OrderCount, OperationCount))

or a formatted string literal:

print(f"Orders: {OrderCount}\nOperations: {OperationCount}\n")

If you wanted to use \r carriage returns to update two lines, you could use ANSI control codes; printing \x1B[2A (ESC [ 2 A) moves the cursor up 2 times, adjust the number as needed. Whether or not this works depends on what platform you are supporting.

On my Mac, the following demo works and updates the two lines with random numbers; I used the ESC [ 0 K to make sure any remaining characters on the line are erased:

import random, time

orders = 0
operations = 0

UP = "\x1B[3A"
CLR = "\x1B[0K"
print("\n\n")  # set up blank lines so cursor moves work
while True:
   orders += random.randrange(1, 3)
   operations += random.randrange(2, 10)

   print(f"{UP}Orders: {orders}{CLR}\nOperations: {operations}{CLR}\n")

   time.sleep(random.uniform(0.5, 2))

Demo:

Animated GIF demonstrating 2 lines updating several times

You could also switch to a full-terminal control with Curses or stick to putting everything on one line. If you are going to go the Curses route, take into account that Windows compatibility is sketchy at best.

like image 113
Martijn Pieters Avatar answered Oct 04 '22 01:10

Martijn Pieters