Retluoc3002
Retluoc3002

Reputation: 29

How can I edit what has already been printed?

For example, let's say one of the printed things is "Hello World" and the second is "Hello". How would I print "Hello" on the same line as the one that says "Hello World"? This is just an example. Realistically I have no idea how long the printed text will be.

Here is an example script:

x = open("file.txt", "r+").read().split("\n")
for i in x:
  print(something)

where something = I don't know. I want the output to be what the first line of the text file says, then what the second line says, and so on except print the second/third/fourth... line over the first line and each line is an unknown length, some shorter than others. Lets say the file.txt says:

Overflow
Stack

I would want it to print "Overflow" then "Stack", except each word gets printed on the first line and once you print "Stack", every part of "Overflow" can't be seen

Keep in mind that print("Hello World", end="\r") won't work because of the length.

Upvotes: 1

Views: 290

Answers (2)

Cnoor0171
Cnoor0171

Reputation: 374

When you use the print function in python, you're just pushing characters onto a pipe somewhere (the pipe might be connected to the standard out, but your program doesn't know that). Once its, pushed, there is nothing you can do to un-push it. Afterall, the pipe might not even be connected to a screen. It might be directly connected to the input of another program, or it might be using a physical printer for display. What would un-pushing even mean in those cases?

There are, however, special control characters (such as the "backspace" character) that you push to the pipe to signal that you want to erase characters. However, The terminal you are connected to is free to do what it wants with these characters. It can respect your wishes and erase characters, or it can print the literal '\b' characters to indicate a backspace, or it can completely ignore you and continue to print after the previous letters. That's completely out of your control.

Assuming the terminal that print the characters supports overwriting the characters, you can use the ANSI control sequences. The sequence for moving cursor to beginning of line is '\033[1G' and for erasing the everything from current cursor position to end of line is '\033[0K'. So,

import time

print('hello world', end='', flush=True) # prints "hello world" with no newline at the end
time.sleep(2) # wait 2 seconds
print('\033[1G\033[0K', end='') # moves cursor to beginning of line and erases the line
print('hi') # prints "hi" with newline at the end

flush=True is needed because the print function is buffered by default and doesn't actually print anything until it hits a newline. This tells the function you want to flush the buffer immediately.

Take a look at ANSI escape codes, section on "CSI sequences" to see what other codes are available.

Upvotes: 1

Tomerikoo
Tomerikoo

Reputation: 19414

You could work around the \r solution by padding each line with spaces according to the previous line:

prev_size = 0
with open("file.txt", "r+") as f:
    for line in f:
        print(f"{line.strip()}{' '*prev_size}", end='\r')
        prev_size = len(line)

You would probably want to add a sleep between prints to be able to actually see the text changing...

Upvotes: 1

Related Questions