Rewrite multiple lines in the console
On Unix, use the curses module.
On Windows, there are several options:
- PDCurses: http://www.lfd.uci.edu/~gohlke/pythonlibs/
- The HOWTO linked above recommends the Console module
- http://newcenturycomputers.net/projects/wconio.html
- http://docs.activestate.com/activepython/2.6/pywin32/win32console.html
Simple example using curses (I am a total curses n00b):
import curses
import time
def report_progress(filename, progress):
"""progress: 0-10"""
stdscr.addstr(0, 0, "Moving file: {0}".format(filename))
stdscr.addstr(1, 0, "Total progress: [{1:10}] {0}%".format(progress * 10, "#" * progress))
stdscr.refresh()
if __name__ == "__main__":
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
try:
for i in range(10):
report_progress("file_{0}.txt".format(i), i+1)
time.sleep(0.5)
finally:
curses.echo()
curses.nocbreak()
curses.endwin()
How to overwrite multiline print in Python?
Use some ANSI escape codes to control your terminal: (from https://stackoverflow.com/a/11474509/8733066)
"\033[F" makes the terminal cursor go up one line, *3 is because there are 3 lines
def status(num, counter):
print("\033[F"*3)
print(
f'Current number {num}',
f'Numbers done: {counter}, all nums: {all_nums}',
f'{(num/all_nums):2.1%}',
sep="\n"
)
# call this before the for loop:
print("\n"*3, end="")
How to rewrite on several terminal lines in Python
It'll depend on the terminal emulator you use, but you probably want the ANSI 'cursor up' codes to be output, which will move the cursor up ready for the next iteration. The code you want is "ESCAPE [ A"
import time
for n in range(1, 10):
print(n)
print(n*2)
time.sleep(1)
print("\033[A\033[A", end="")
An ESCAPE is character 27, which is 033 in octal.
Note the end="" to stop the cursor moving down again...
C++ - Overwrite Multiple Lines that were Previously Output to Console
You can use SetConsoleCursorPosition
to set the cursor position.
Python 3 Print Update on multiple lines
\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:
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.
Terminal - How to overwrite many lines?
The colorama third party module has support for changing the position of the cursor, via the "\x1b[?:?H" command string. You can also clear the screen this way.
import colorama
colorama.init()
def put_cursor(x,y):
print "\x1b[{};{}H".format(y+1,x+1)
def clear():
print "\x1b[2J"
clear()
put_cursor(0,0)
print "hello"
print "huhu"
#return to first line
put_cursor(0,0)
print "noooooo"
The module appears to do this by importing ctypes and invoking windll.kernel32.SetConsoleCursorPosition
. See win32.py, line 58.
Replace multi-line string in terminal
You haven't specified if you need solution working on Linux or Windows.
For Linux you can use zwer answer. However curses module is not available on Windows.
Windows cmd is very simple and doesn't understand advanced formatting.
You have clear and redraw the whole window to get animation.
Here is an example of a star moving randomly on board for 20 frames of animation:
import os
import time
import random
import copy
board = [['+', '-', '-', '-', '-', '-', '-', '-', '-', '+'],
['|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|'],
['|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|'],
['|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|'],
['|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|'],
['|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|'],
['|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|'],
['|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|'],
['|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|'],
['+', '-', '-', '-', '-', '-', '-', '-', '-', '+']]
for i in range(20):
os.system('cls')
frame = copy.deepcopy(board)
frame[random.randint(1, 8)][random.randint(1, 8)] = '*'
print('\n'.join([''.join(i) for i in frame]))
time.sleep(1)
Related Topics
Convert Pandas Timezone-Aware Datetimeindex to Naive Timestamp, But in Certain Timezone
How Slow Is Python's String Concatenation VS. Str.Join
How to Start a Python File While Windows Starts
How to Split a String of Space Separated Numbers into Integers
Convert Python Sequence to Numpy Array, Filling Missing Values
Calling a Python Script with Input Within a Python Script Using Subprocess
How to Find the Exact Intersection of a Curve (As Np.Array) with Y==0
Check If Something Is (Not) in a List in Python
Attributeerror: 'Module' Object Has No Attribute
Why Is Python 3.X's Super() Magic
How to Get the Original Variable Name of Variable Passed to a Function