Problem
In the two years that I've been coding in python, I've somewhere and somewhere struggled with this problem and therefore I want to ask for the correct way. How do you make it so that it overwrites the previous print, while having newlines (either by returns or \n). I've tried most answers that I could find, however it only does one of the jobs I want it to.
Testing model
import time, sys
counter1 = 0
counter2 = 0
counter3 = 0
for i in range(5):
time.sleep(0.1)
counter1 = 1
counter2 = 1
counter3 = 1
#print method here!
Attempt 1:
Multiple lined (f)string using """
and \r
print(f"""\r
Counter 1: {counter1}
Counter 2: {counter2}
Counter 3: {counter3}
""")
Output of attempt 1:
Counter 1: 1
Counter 2: 1
Counter 3: 1
Counter 1: 2
Counter 2: 2
Counter 3: 2
..etc
Attempt 2:
A normal (f)string using \r
and \n
print(f"\rCounter 1: {counter1}\nCounter 2: {counter2}\nCounter 3: {counter3}")
Output of attempt 2:
Counter 1: 1
Counter 2: 1
Counter 3: 1
Counter 1: 2
Counter 2: 2
Counter 3: 2
etc..
Attempt 3:
Using sys.stdout.write
, \r
and \n
sys.stdout.write(f'\rCounter 1: {counter1}\nCounter 2: {counter2}\nCounter 3: {counter3}')
sys.stdout.flush()
Output of attempt 3:
Counter 1: 1
Counter 2: 1
Counter 1: 2
Counter 2: 2
Counter 1: 3
etc..
Attempt 4:
Using the carriage return (\r
) at the end:
print(f"Counter 1: {counter1}\nCounter 2: {counter2}\nCounter 3: {counter3}\n", end = "\r")
Output of attempt 4:
Counter 1: 1
Counter 2: 1
Counter 3: 1
Counter 1: 2
Counter 2: 2
Counter 3: 2
Attempt 5:
Prints apart from each other with the first one having \r
in front of it
print(f"\rCounter 1: {counter1}")
print(f"Counter 2: {counter2}")
print(f"Counter 3: {counter3}")
Output of attempt 5:
Counter 1: 1
Counter 2: 1
Counter 3: 1
Counter 1: 2
Counter 2: 2
Counter 3: 2
CodePudding user response:
Carriage return doesn't undo an entire print or anything, it just returns the cursor to the first column of the current line. Think of the carriage on a typewriter returning to the left side. If you have a newline before the carriage return, then the cursor will just be at the left side of the line below the one you just printed.
To do what you're trying to do, and overwrite previous lines, you'd have to do something like re-print the entire screen's worth of lines, or use something like curses that does it for you.
CodePudding user response:
Adding to alefir's answer, the closest I could come up with was something like this, which puts everything you want to change onto one line. Not sure if it meets the need for your code.
import time
counter1 = 0
counter2 = 0
counter3 = 0
print("%s\t%s\t%s" % ("Counter 1 name", "Counter 2 name", "Counter 3 name"))
for i in range(5):
time.sleep(0.1)
counter1 = 1
counter2 = 1
counter3 = 1
print("%.1f\t\t%.1f\t\t%.1f" % (counter1, counter2, counter3), end = "\r")
Alternatively, to implement alefir's approach with multiple lines, you could use something like this to clear the screen:
# import only system from os
from os import system, name
# define our clear function
def clear():
# for windows
if name == 'nt':
_ = system('cls')
# for mac and linux(here, os.name is 'posix')
else:
_ = system('clear')
Combining with your attempt 1, you would have something like this:
for i in range(5):
time.sleep(0.1)
counter1 = 1
counter2 = 1
counter3 = 1
clear()
print(f"""\r
Counter 1: {counter1}
Counter 2: {counter2}
Counter 3: {counter3}
""")