Is there a way to clear your printed text in python? - python

I have wanted for a long time to find out how to clear something like print("example") in python, but I cant seem to find anyway or figure anything out.
print("Hey")
>Hey
Now I need to clear it, and write some new text.
print("How is your day?")
It would print.
Hey
>How is your day?
But I want to clear the "Hey" so the user shouldnt look at both at same time, and it looks kinda messy.

import os
os.system('cls')
Or os.system('clear') on unix (mac and linux). If you don't want the scroll up either, then you can do this:
os.system("printf '\033c'") should get rid of scroll back too. Something that works on all systems:
import os
os.system('cls' if os.name == 'nt' else "printf '\033c'")

I think this is what you want to do:
take the cursor one line up and delete the line
this can be done like using the code below
import sys
import time
def delete_last_line():
"Use this function to delete the last line in the STDOUT"
#cursor up one line
sys.stdout.write('\x1b[1A')
#delete last line
sys.stdout.write('\x1b[2K')
########## FOR DEMO ################
if __name__ == "__main__":
print("hello")
print("this line will be delete after 2 seconds")
time.sleep(2)
delete_last_line()
####################################

Small addition into #Aniket Navlur 's answer in order to delete multiple lines:
def delete_multiple_lines(n=1):
"""Delete the last line in the STDOUT."""
for _ in range(n):
sys.stdout.write("\x1b[1A") # cursor up one line
sys.stdout.write("\x1b[2K") # delete the last line

Well I have a temporary way:
print("Hey", end="")
for i in range(4):
print('\b', end = '')
print("How is your day?")

The escape character \r (carriage return), means "start printing from beginning of this line".
But some of operating systems use it as 'newline'.
Following would work in Linux:
import time
import sys
#first text
print('Hey.', end="")
#flush stdout
sys.stdout.flush()
#wait a second
time.sleep(1)
#write a carriage return and new text
print('\rHow is your day?')

Related

How to delete print

Here's the problem. In the following code, I wish to produce a 'moving cursor' effect. Here's the code:
sys.stdout.write('\033[2K\033[1G')
time.sleep(2)
print ('virus_prevention.fix.virus.|attempt_enter')
time.sleep(2)
sys.stdout.write('\033[2K\033[1G')
print ('virus_prevention.fix.virus|.attempt_enter')
time.sleep(0.1)
sys.stdout.write('\033[2K\033[1G')
print ('virus_prevention.fix.viru|s.attempt.enter')
time.sleep(0.1)
sys.stdout.write('\033[2K\033[1G')
print('virus_prevention.fix.vir|us.attempt.enter')
time.sleep(0.1)
sys.stdout.write('\033[2K\033[1G')
print ('virus_prevention.fix.vi|rus.attempt.enter')
time.sleep(0.1)
sys.stdout.write('\033[2K\033[1G')
print ('virus_prevention.fix.v|irus.attempt.enter')
time.sleep(0.1)
sys.stdout.write('\033[2K\033[1G')
print ('virus_prevention.fix.|virus.attempt.enter')
time.sleep(2)
sys.stdout.write('\033[2K\033[1G')
print ('virus_prevention.fix|virus.attempt.enter')
And this is the output:
[2K[1Gvirus_prevention.fix.virus.|attempt_enter
[2K[1Gvirus_prevention.fix.virus|.attempt_enter
[2K[1Gvirus_prevention.fix.viru|s.attempt.enter
[2K[1Gvirus_prevention.fix.vir|us.attempt.enter
[2K[1Gvirus_prevention.fix.vi|rus.attempt.enter
[2K[1Gvirus_prevention.fix.v|irus.attempt.enter
[2K[1Gvirus_prevention.fix.|virus.attempt.enter
And the sys.stdout.write doesn't really help. It just ends up with added text on the front of the current text. So if there are solutions anyone is willing to share (Python 3) please do. (I did have a solution which used repeatedly clearing the screen via os.system('clear'), which I don't really want to use.)
sys.stdout.write is a good start, but you also need to pass a "carriage return" '\r' to jump to the beginning of the line. This will overwrite the old characters with the next call:
for i in range(10):
sys.stdout.write(str(i)+'\r')
time.sleep(1)
If the new line is shorter than the previous line, you will still see the additional characters of the previous line. As a fix you can add some additional spaces to overwrite them.
The main difference between sys.stdout.write and print is, that print will automatically append a linebreak (\n). This is why you see the sys.stdout.write infront of the next printed line.
Running this in an interactive Python session has some weird side effects, but it is fine if you use it in a Python script. Also, make sure not to have any other print() commands inbetween. This only works on the current line, and any '\n' creates a new line.
sys.stdout.write('virus_prevention.fix.virus.|attempt_enter\r')
time.sleep(2)
sys.stdout.write('virus_prevention.fix.virus|.attempt_enter\r')
print() # create a linebreak at the end
This is similar to what you wish to achieve, you will need to adjust it to work with where you want the 'cursor' to show
import time
displayText = "Python"
character = '|'
for i in range(len(displayText)+1):
print(displayText[:i] + character + displayText[i:], end='\r')
time.sleep(.2)
input()
This will give the desired effect when executed via console/command prompt; but not through Python's IDLE Shell.

Whole program typing effect

I'm making a text adventure game in Python 3. Is there any way to add a typing effect to any text that gets printed without repeating a command after every line?
Assuming that with "typing effect" you mean that the messages should slowly appear one character at a time, you can define a function that iterates the given message and prints it one character at a time, using time.sleep in between to wait a bit. Make sure to flush the buffer after each character.
import time
def slow_print(msg):
for c in msg:
print(c, end="", flush=True)
time.sleep(0.1)
print()
slow_print("Hello World!")
If you really want to apply this for each and every output in your game (which I'd really not recommend) you can overwrite the print function, keeping a reference to the original print function to use within your new slow print function.
original_print = print
def slow_print(msg):
# same as above, but using original_print instead of print
print = slow_print
print("Hello World!")
You could also just def print(...) directly, but I'd recommend defining it as a separate function and then assigning it to print. This way, you can still make this optional, as this will most likely annoy the player after the first few minutes.
I assume you want the characters to appear as if someone were typing them so I'll just assume that
Import modules
import os
import sys
import time
from colr import color
Define your function
def function_name(phrase,speed,r_value,g_value,b_value):
for char in phrase:
sys.stdout.write(color(char, fore=(r_value,g_value,b_value)))
sys.stdout.flush()
time.sleep(speed)
Test the function
function_name("Hello",0.05,0,255,0)
#prints the phrase "Hello" in green text
Alternatively you could write the function using the threading library, which would allow users to skip the typing effect if they so wish.
import time, threading, os, sys, tty, termios
from colr import color
def slow_type_interrupt(phrase,speed,r_value,g_value,b_value):
done = False # this acts as the kill switch, using if statements, you can make certain button presses stop the message printing and outright display it
def type_out():
for char in phrase:
if done:
break
sys.stdout.write(color(char,fore=(r_value,g_value,b_value)))
sys.stdout.flush()
time.sleep(speed)
os.system('clear')
print(color(phrase,fore=(r_value,g_value,b_value)))
t = threading.Thread(target=type_out)
t.start()
def getkey():
ky = sys.stdin.fileno()
Ab = termios.tcgetattr(ky)
try:
tty.setraw(sys.stdin.fileno())
key = sys.stdin.read(1)
finally:
termios.tcsetattr(ky, termios.TCSADRAIN, Ab)
return key
while not done:
key_press = getkey()
if key_press == 'a': #You can replace a with whatever key you want to act as the "kill key"
done = True
os.system('clear')
print(color(phrase,fore=(r_value,g_value,b_value)))
slow_type_interrupt("Hello this is a test. Pressing 'a' will end this and immediatley display the message",.05,0,255,0)
As I mentioned in the comments of the code, a can be replaced by whatever you want. The reason I use this particular method for retrieving keypresses is because it works on almost anything that runs Python. I would suggest reading up on some other ways to retrieve keyboard inputs.
Hope I could help :)

How do I overwrite a line in Python

I have created a simple python program that will count up to 10
What I am trying to achieve is for the program to delete the previous number and print the new number
This is the code that I have created:
import sys
import time
for i in range(10):
text = "\r" + str(i)
sys.stdout.write(text)
sys.stdout.flush()
time.sleep(1)
Which outputs:
0123456789
Changing the code to have the "\r" after the str(i) didn't work either
import sys
import time
for i in range(10):
text = str(i) + "\r"
sys.stdout.write(text)
sys.stdout.flush()
time.sleep(1)
Which also resulted in:
0123456789
I was looking for it to count up, and display at the end only the 9 however it doesn't overwrite the previous numbers
Edit:
I am using Windows, Python3
Edit 2:
How to overwrite the previous print to stdout in python? Does not give me a working answer, it still doesn't do what I want
Therefore due to my excellent reasoning it is not a duplicate :P
As an alternative, you can clear the whole window, by using os.system("cls")
There are some control symbols accepted by virtual terminals. One of them is '\b' that moves a carret for one place back. This one is accepted on Windows too and I will use it in my example below. Unix terminals accept a lot more of controls including color changes and more.
from time import sleep
import sys, os
def clear ():
os.system("cls" if sys.platform.startswith("win") else "clear")
clear()
s = "1"
sys.stdout.write(s)
for x in range(2, 21):
sleep(1)
# Return carret to beginning of line:
l = len(s)
s = l*"\b"
sys.stdout.write(s)
# Clear line (just in case):
s = l*" "
sys.stdout.write(s)
# Return to the beginning again:
s = l*"\b"
sys.stdout.write(s)
# Write over new text:
s = str(x)
sys.stdout.write(s)
Use the end parameter to specify a "\r" as the line ending.
import time
for i in range(10):
print(i, end="\r")
time.sleep(1)
I would do it like this:
for x in range(10):
print("{}".format(x), end="\r")
I believe your code should work perfectly fine. The problem should be that you are using a Windows terminal. Try using Linux. Most code does not work in Windows. You can refer this link to know why you have to stop using python on Windows.
This is also an alternate code you can try.
import time
for i in range(10):
text = str(i)
print(text,end = "\r")
time.sleep(1)
Why not use the standard print of python? Althougth given in many debugger screens this tends to not work. In terminal (ubuntu) it does
import time
for i in range (10):
print(i, end='\r')
time.sleep(1)
Probably for stdout something exists too but in this case I usually use the print of python3

How to clear only last one line in python output console?

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.
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
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)
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).
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))
For Python 3's, using f-String.
from time import sleep
for i in range(61):
print(f"\r{i}", end="")
sleep(0.1)
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.
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.
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 "

Loading animation in python

Im new to python and was wondering how to make a loading animation while my program runs. I need this because I don't want users thinking that the program is caught in a dead loop. I prefer a something like...
Loading...(with the dots disappearing and reappearing one by one)
Thanks!
If your output window supports the carriage return character, you can print it to make the cursor return to the beginning of the current line (provided you end your print statement with a comma, so a newline character isn't automatically printed). Then subsequent prints will overwrite what was already printed. You can use this to do very simple one line animation. Example:
import time
print "Starting program."
print "Loading ",
time.sleep(1) #do some work here...
print "\rLoading. ",
time.sleep(1) #do some more work here...
print "\rLoading.. ",
time.sleep(1) #do even more work...
print "\rLoading...",
time.sleep(1) #gratuitious amounts of work...
print "\rLoading ",
... Where time.sleep(1) is a placeholder representing the actual work you want to do.
Result:
Starting program.
Loading
Then, one second later:
Starting program.
Loading.
Then, one second later:
Starting program.
Loading..
Then, one second later:
Starting program.
Loading...
Then, one second later:
Starting program.
Loading
etc.
Compatibility note: in 3.X, print is no longer a statement, and the "end with a comma" trick no longer works. Instead, specify the end parameter:
print("\rLoading...", end="")
The most proper way I can think of to do it would be using threading.
You would initiate a thread that starts displaying some indication that the program is doing something and then open a new thread that actually does the work.
When the thread doing the work finished then you can move on with whatever else the program does.
This looks ok when ran in windows command prompt, not sure how linux will like it:
import threading
import time
import os
import queue
q = queue.Queue()
q.put(False)
class counter(object):
def __init__(self):
wait_label = "Loading"
self.stop_flag = q.get()
while not self.stop_flag:
try:
self.stop_flag = q.get_nowait()
except:
pass
os.system('cls') # might need to change this command for linux
wait_label += "."
print(wait_label)
time.sleep(1)
class other(counter):
def __init__(self):
time.sleep(15)
q.put(True)
counter_thread = threading.Thread(None, counter)
counter_thread.start()
other_thread = threading.Thread(None, other)
other_thread.start()
To reduce the code length, we can loop it.
import time
# flag variable to print the dots and it's value increases inside the while loop.
flag = 1
# To print the dots we use while loop. In total, 4 dots will be printed.
while flag < 5:
print("\rLoading, Please Wait " + ("." * flag), end=" ")
time.sleep(1)
flag = flag + 1

Categories

Resources