14

I am trying to clear only last few line from output console window. To achieve this I have decided to use create stopwatch and I have achieved to interrupt on keyboard interrupt and on enter key press it creates lap but my code only create lap once and my current code is clearing whole output screen.

clear.py

import os
import msvcrt, time
from datetime import datetime
from threading import Thread

def threaded_function(arg):
    while True:
        input()

lap_count = 0
if __name__ == "__main__":
    # thread = Thread(target = threaded_function)
    # thread.start()
    try:
        while True:
            t = "{}:{}:{}:{}".format(datetime.now().hour, datetime.now().minute, datetime.now().second, datetime.now().microsecond)
            print(t)
            time.sleep(0.2)
            os.system('cls||clear') # I want some way to clear only previous line instead of clearing whole console
            if lap_count == 0:
                if msvcrt.kbhit():
                    if msvcrt.getwche() == '\r': # this creates lap only once when I press "Enter" key
                        lap_count += 1
                        print("lap : {}".format(t))
                        time.sleep(1)
                        continue            
    except KeyboardInterrupt:
        print("lap stop at : {}".format(t))
        print(lap_count)

when I run

%run <path-to-script>/clear.py 

in my ipython shell I am able to create only one lap but it is not staying for permanent.

Gahan
  • 4,075
  • 4
  • 24
  • 44
  • The answer at [this](https://stackoverflow.com/a/38541614/7664524) post has quite good explanation and option on cases with Python 2, Python 3, IPython notebook and jupyter notebook. – Gahan Aug 23 '20 at 12:32

8 Answers8

11

To clear only a single line from the output :

print ("\033[A                             \033[A")

This will clear the preceding line and will place the cursor onto the beginning of the line. If you strip the trailing newline then it will shift to the previous line as \033[A means put the cursor one line up

mr_pool_404
  • 488
  • 5
  • 16
7

I think the simplest way is to use two print() to achieve clean the last line.

print("something will be updated/erased during next loop", end="")
print("\r", end="")
print("the info")

The 1st print() simply make sure the cursor ends at the end of the line and not start a new line

The 2nd print() would move the cursor to the beginning of the same line and not start a new line

Then it comes naturally for the 3rd print() which simply start print something where the cursor is currently at.

I also made a toy function to print progress bar using a loop and time.sleep(), go and check it out

def progression_bar(total_time=10):
    num_bar = 50
    sleep_intvl = total_time/num_bar
    print("start: ")
    for i in range(1,num_bar):
        print("\r", end="")
        print("{:.1%} ".format(i/num_bar),"-"*i, end="")
        time.sleep(sleep_intvl)
Jason
  • 3,166
  • 3
  • 20
  • 37
  • 2
    This is actually the best answer concerning the deletion of a line! – Yehla Dec 02 '21 at 18:53
  • You need to add `print("\r", end="") print("{:.1%} ".format(1), "-" * num_bar, end="")` to the end of the function or it stops at 98%. Otherwise this was really helpful thanks! – JWCompDev Mar 09 '22 at 07:16
6

The codes shared by Ankush Rathi above this comment are probably correct, except for the use of parenthesis in the print command. I personally recommend doing it like this.

print("This message will remain in the console.")

print("This is the message that will be deleted.", end="\r")

One thing to keep in mind though is that if you run it in IDLE by pressing F5, the shell will still display both messages. However, if you run the program by double clicking, the output console will delete it. This might be the misunderstanding that happened with Ankush Rathi's answer (in a previous post).

bad_coder
  • 11,289
  • 20
  • 44
  • 72
  • 1
    If the message is long and spans more than one line, only the last line will be deleted, not the entire message. (Only tried with the Terminal app in Ubuntu, actually). – Alpi Murányi Jan 02 '21 at 04:13
4

I know this is a really old question but i couldn't find any good answer at it. You have to use escape characters. Ashish Ghodake suggested to use this

print ("\033[A                             \033[A")

But what if the line you want to remove has more characters than the spaces in the string? I think the better thing is to find out how many characters can fit in one of your terminal's lines and then to add the correspondent number of " " in the escape string like this.

import subprocess, time
tput = subprocess.Popen(['tput','cols'], stdout=subprocess.PIPE)
cols = int(tput.communicate()[0].strip()) # the number of columns in a line
i = 0
while True:
    print(i)
    time.sleep(0.1)
    print("\033[A{}\033[A".format(' '*cols))
    i += 1

finally I would say that the "function" to remove last line is

import subprocess
def remove():
    tput = subprocess.Popen(['tput','cols'], stdout=subprocess.PIPE)
    cols = int(tput.communicate()[0].strip())
    print("\033[A{}\033[A".format(' '*cols))
bad_coder
  • 11,289
  • 20
  • 44
  • 72
Giuppox
  • 1,393
  • 9
  • 35
  • 1
    Why do `''.join([' ']*cols)` instead of just `' '*cols`? – magikarp Apr 18 '21 at 17:07
  • 1
    @Shreya At the time I wrote the answer I didn't know much Python and string multiplication seemed strange to me. However there is not any particular reason why it can't be `' '*cols`, corrected it. – Giuppox Apr 18 '21 at 18:25
2

Found a solution on this page that works. Here is the helper function:

import sys

def delete_last_line():
    "Deletes the last line in the STDOUT"
    # cursor up one line
    sys.stdout.write('\x1b[1A')
    # delete last line
    sys.stdout.write('\x1b[2K')

I hope it helps someone.

Pedram Elmi
  • 151
  • 8
1

For Python 3's, using f-String.

from time import sleep
for i in range(61):
    print(f"\r{i}", end="")
    sleep(0.1)
Gооd_Mаn
  • 343
  • 1
  • 16
0

None of the other answers worked for me. Putting print("Sentence to be overwritten", end='\r') would instantly clear my sentence and it would never be visible to begin with. I'm using PyCharm on a Mac if that could be making the difference. What I had to do is the following:

from time import sleep
print("Sentence to be overwritten", end='')
sleep(1)
print("\r", end='') 
print("Sentence to stay")

end='' makes it so the print doesn't automatically put a '\n' character at the end. Then print("\r", end='') will put the cursor at the beginning of the line. Then the 2nd print statement will be printed in the same spot as the first, overwriting it.

nhershy
  • 643
  • 1
  • 6
  • 20
-1

If you intend to delete certain line from the console output,

print "I want to keep this line"
print "I want to delete this line",
print "\r " # this is going to delete previous line

or

print "I want to keep this line"
print "I want to delete this line\r "
Ankush Rathi
  • 622
  • 1
  • 6
  • 26