'\b' doesn't print backspace in PyCharm console - python

I am trying to update the last line in PyCharm's console. Say, I print a and then I want to change it to c. However, I encounter the following problem. When I run:
print 'a\bc'
it prints
a c
while the desired output (which is also what I see in the Windows console) is:
c
Is there a way to move the cursor back in PyCharm's console? or maybe delete the whole line?

This is not a bug, this is a limitation of the interactive console found both in PyCharm, and in the IDLE shell.
When using the command prompt of windows, or a linux shell - the \b character is interpreted as a backspace and implemented as it is being parsed - However, in the interactive console of PyCharm and IDLE the \b character and many others are disabled, and instead you simply get the ASCII representation of the character (a white space in most cases).

It's a known bug: http://youtrack.jetbrains.com/issue/PY-11300
If you care about this, please get an account on the bug tracker and upload the bug to give it more attention.

The \r works. I know this is ASCII Carriage Return, but i use this as a workaround
print("\ra")
print("\rc")
will yield in c in the console
By the way, backspace is a ASCII Character

I just ran into the same issue in PyCharm (2019.1) and stumbled on this post. It turns out that you can use the \b character if you use the sys.stdout.write function instead of print. I wasn't able to get any of the above examples working within PyCharm using the print function.
Here's how I update the last line of text in my code assuming I don't need more than 100 characters:
# Initialize output line with spaces
sys.stdout.write(' ' * 100)
# Update line in a loop
for k in range(10)
# Generate new line of text
cur_line = 'foo %i' % k
# Remove last 100 characters, write new line and pad with spaces
sys.stdout.write('\b' * 100)
sys.stdout.write(cur_line + ' '*(100 - len(cur_line)))
# ... do other stuff in loop
This should generate "foo 1", then replaced with "foo 2", "foo 3", etc. all on the same line and overwriting the previous output for each string output. I'm using spaces to pad everything because different programs implement the backspace character differently, where sometimes it removes the character, and other times it only moves the cursor backwards and thus still requires new text to overwrite.
I've got to credit the Keras library for this solution, which correctly updates the console output (including PyCharm) during learning. I found that they were using the sys.stdout.write function in their progress bar update code.

Related

What does this mean in Python '\x1b[2K'?

I've just learnt that to clear a line that you printed in Python, do this:
sys.stdout.write('\x1b[2K')
Why is it so complicated? what does that weird code mean? and is there any alternative in print command?
Print does offer "end" option that allows to go back and forth in lines, but no way to clear what you printed. Overwriting via \r doesn't always work especially if the new line is shorter than the old one. You will get traces from the old line, so I need clearing first.
Thanks.
\x1b[2K is what's known as an ANSI terminal control sequence. They are a legacy of the 1970s and still used today (but vastly extended) to control terminal emulators.
\x1b is the ASCII for ESCAPE (literally the ESC key on your keyboard). [2K is the command "erase the current line".
There are many libraries in Python for working with the terminal, such as Urwid. These libraries will hide the inner workings of the terminal from you and give you higher-level constructs to create TUIs.
However, there is a much more efficient way of doing this:
You can use the print() command as usual, and delete the screen using
os.system("cls") # For Windows
or
os.system("clear") # For Linux
Alternative to print on a single line
I have a script that prints the x, y coordinates of the mouse as such:
import pyautogui
import time
while True:
x, y = pyautogui.position()
position_string = "X: {} Y: {}".format(str(x).rjust(4), str(y).rjust(4))
print(position_string, end='')
print('\b' * len(position_string), end='', flush=True)
time.sleep(1)
Where I will point out that you can print the backspace character ('\b') the amount of times that there are characters on the screen (len(position_string)), and when used with the end='' and flush=True options this will constantly print on a single line within your console. I should also note that this does not work in IDLE, but only on an actual command line! In IDLE the backspace characters are actually printed as some weird square shape...
This is called ANSI escape code . 2K is the name for Erase in Line. Quote from the link:
Erases part of the line. If n is 0 (or missing), clear from cursor to the end of the line. If n is 1, clear from cursor to beginning of the line. If n is 2, clear entire line. Cursor position does not change.
You can also try echo -e '\x1b[2k' in the terminal for better understanding.

Why do I get different outputs with \r escape sequence in different IDLE?

When is used the \r in sublime, it behaved as a \n escape sequence.
carriage_return = "I will use a carriage\rreturn"
print (carriage_return)
I will use a carriage
return
But when I used it in the python 3.7.2 IDLE, the output was:
I will use a carriagereturn
Why is there's a different output?
How do you use the \r escape sequence?
A "carriage return" traditionally moved the cursor back to the beginning of the line so you should have seen the output as:
return use a carriage
because the i will would have been overwritten.
However, this tradition has now changed as standards have developed and there is no more uniform handling of a "carriage return". For example, HTML treats a \r as a whitespace.
Since I am new to stackoverflow please tell me how to improve my answer.

Unprint a line on the console in Python?

Is it possible to manipulate lines of text that have already been printed to the console?
For example,
import time
for k in range(1,100):
print(str(k)+"/"+"100")
time.sleep(0.03)
#>> Clear the most recent line printed to the console
print("ready or not here I come!")
I've seen some things for using custom DOS consoles under Windows, but I would really like something that works on the command_line like does print without any additional canvases.
Does this exist? If it doesn’t, why not?
P.S.: I was trying to use curses, and it was causing problems with my command line behaviour outside of Python. (After erroring out of a Python script with curses in it, my Bash shell stopped printing newline -unacceptable- ).
What you're looking for is:
print("{}/100".format(k), "\r", end="")
\r is carriage return, which returns the cursor to the beginning of the line. In effect, whatever is printed will overwrite the previous printed text. end="" is to prevent \n after printing (to stay on the same line).
A simpler form as suggested by sonrad10 in the comments:
print("{}/100".format(k), end="\r")
Here, we're simply replacing the end character with \r instead of \n.
In Python 2, the same can be achieved with:
print "{}/100".format(k), "\r",
What you need are ANSI Command Codes.
http://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes
You also need code to activate ANSI Command Codes. I would use Colorama.
https://pypi.python.org/pypi/colorama
OR
Use curses (Python 3.4+) module.
The simplest method (at least for Python 2.7) is to use the syntax:
print 'message', '\r',
print 'this new message now covers the previous'
Notice the extra ',' at the end of the first print. This makes print stay on the same line. Meanwhile, the '\r' puts the print at the beginning of that line. So the second print statement overwrites the first.

PDFtotext - whitespace showing as aacute on commandline

I am extracting text using python from a textfile created from pdf using pdftotext. It is one of 2000 files and in this particular one, a line of keywords ends in EU. The remainder of the line is blank to the naked eye and so is the following line.
The program normally strips off any trailing blanks at the end of a line and ignores the subsequent blank line.
In this instance, it is saving the whitespace which is seen when it is printed out in at textfile between "EU. " and similarly in html (Simile Exhibit).
I also printed to the command line and here I see a string of aacute. [?]
I thought the obvious way to deal with this was to search and replace the accute. I've tried to do that with a compile statement and I've played with permutations of decoding the incoming text.
Oddly though, when I print "\255" I don't get an aacute, I get an o grave.
It seems likely with this odd combination of errors that I have misunderstood something fundamental. Any tips of how to begin unravelling this?
Many thanks.
The first tip is not to print wildly to all possible output mechanisms using various unstated encodings. Find out exactly what you have got. Do this:
print repr(the_line_with_the_problem) # Python 2.x
print(ascii(the_line_with_the_problem)) # Python 3.x
and edit your question and copy/paste the result.
Second tip: When asking for help, give information about your environment:
What version of Python? What version of what operating system?
Also show locale-related info; following example is from my computer running Python 2.7 in a Windows 7 Command Prompt window::
>>> import sys, locale
>>> sys.getdefaultencoding()
'ascii'
>>> sys.stdout.encoding
'cp850'
>>> locale.getdefaultlocale()
('en_AU', 'cp1252')
>>>
Third tip: Don't use your own jargon ... the concepts "Simile Exhibit", "printed to the command line", and "compile statement" need explanation.
What is the relevance of "\255"? Where did you get that from?
Wild guesses while waiting for some facts to emerge:
(1) The offending character is U+00A0 NO-BREAK SPACE aka NBSP which appears in your text as "\xA0" and when sent to stdout in a Western European locale on Windows using a Command Prompt window would be treated as being encoded in cp850 and thus appear as a-acute. How this could be transmogrified into o-grave is a mystery.
(2) "\255" == \xAD implies the offending character is U+00AD SOFT HYPHEN but why this would be seen as o-grave is a mystery, and it's not "whitespace"; it shouldn't be shown at all, and it it is shown it should be as a hyphen/minus-sign, not a space.

Python print statement prints nothing with a carriage return

I'm trying to write a simple tool that reads files from disc, does some image processing, and returns the result of the algorithm. Since the program can sometimes take awhile, I like to have a progress bar so I know where it is in the program. And since I don't like to clutter up my command line and I'm on a Unix platform, I wanted to use the '\r' character to print the progress bar on only one line.
But when I have this code here, it prints nothing.
# Files is a list with the filenames
for i, f in enumerate(files):
print '\r%d / %d' % (i, len(files)),
# Code that takes a long time
I have also tried:
print '\r', i, '/', len(files),
Now just to make sure this worked in python, I tried this:
heartbeat = 1
while True:
print '\rHello, world', heartbeat,
heartbeat += 1
This code works perfectly. What's going on? My understanding of carriage returns on Linux was that it would just move the line feed character to the beginning and then I could overwrite old text that was written previously, as long as I don't print a newline anywhere. This doesn't seem to be happening though.
Also, is there a better way to display a progress bar in a command line than what I'm current trying to do?
Try adding sys.stdout.flush() after the print statement. It's possible that print isn't flushing the output until it writes a newline, which doesn't happen here.
Handling of carriage returns in Linux differs greatly between terminal-emulators.
Normally, one would use terminal escape codes that would tell the terminal emulator to move the virtual "carriage" around the screen (think full-screen programs running over BBS lines). The ones I'm aware of are the VT100 escape codes:
\e[A: up
\e[B: down
\e[C: right
\e[D: left
\e[1~: home
\e[4~: end
Where \e is the escape character, \x1b.
Try replacing all \r's with \e[1~
Also see this post
If your terminal is line-buffered, you may need a sys.stdout.flush() to see your printing if you don't issue a linefeed.

Categories