1

I am running Python 3 in the Jupyter notebook. Typing in:

print('hello \b\b\b\b\b\b goodbye')

does not return just goodbye as you would expect. Instead it returns hell goodbye, so only 2 characters are erased by the 6 backspaces.

The same code works correctly in the Python console and in the IPython notebook in the terminal, so why is it not working in Jupyter?

Tofi
  • 229
  • 1
  • 7
  • Interestingly, when you have an even number of `\b` (no matter whether it is 4 or 10), it seems to have the effect of erasing the previous two characters. And, if the number of `\b` is odd, it has a different effect, but the effect is the same regardless of whether you have 1 or 11 of them – fountainhead Mar 31 '19 at 10:59
  • The effect seems to depend only upon whether you have an even number of `\b` or an odd number of them. – fountainhead Mar 31 '19 at 11:03
  • I thought the explanation might be that each `\b` has the effect of erasing the previous one, but then, if that were true, an even number of `\b` should result in no erasure at all. – fountainhead Mar 31 '19 at 11:04
  • There is some relevant info at https://stackoverflow.com/questions/9667462/backspace-behavior-in-python-statement-what-is-correct-behavior-of-printing-a. but it still doesn't explain why the effect is the same for any even number of `\b` – fountainhead Mar 31 '19 at 11:15
  • Yeah me too, though assuming that the `\b` are executed from right to left does not explain it. – Tofi Mar 31 '19 at 11:16

1 Answers1

2

First of all, as mentioned at this thread, backspace isn't meant to erase the character to the left. It is meant to act only as the "left arrow". EDIT: as mentioned in OP's comment below, in Jupyter notebook this doesn't seem to hold -- the \b does have the effect of erasing, in Jupyter notebook.

Secondly, there seems to be some anomaly in the behavior of backspace as seen on Jupyter notebook. (I couldn't find the anomaly when I ran the same tests by simply running python on the conda prompt on my Windows, and the behavior was exactly as expected). The anomaly is that, an odd number of consecutive backspaces seems to behave exactly like a single backspace, and an even number of backspaces seems to always behave like two consecutive backspaces. As I said, on raw Python on the conda prompt, the effect of 3 consecutive backspaces is different from the effect of a single backspace, and that is how it is supposed to be.

Here's the test I ran, first as a code snippet in a Jupyter notebook cell, and second as a Python script on the conda prompt:

print('00hello goodbye')
print('01hello\b goodbye')
print('02hello\b\b goodbye')
print('03hello\b\b\b goodbye')
print('04hello\b\b\b\b goodbye')
print('05hello\b\b\b\b\b goodbye')
print('06hello\b\b\b\b\b\b goodbye')
print('07hello\b\b\b\b\b\b\b goodbye')
print('08hello\b\b\b\b\b\b\b\b goodbye')

Output in Jupyter notebook:

00hello goodbye
01hell goodbye
02hel goodbye
03hell goodbye
04hel goodbye
05hell goodbye
06hel goodbye
07hell goodbye
08hel goodbye

Output on command prompt:

00hello goodbye
01hell goodbye
02hel goodbye
03he goodbye
04h goodbye
05 goodbye
0 goodbye
 goodbye
 goodbye

EDIT: To summarize the above rant, the behavior is very different in Jupyter notebook vs command prompt. And the difference is in two aspects (a) Backspace acting as an erase (b) Multiple consecutive (odd or even number of) backspaces getting collapsed into 1 or 2 backspaces. Both these anomalies don't seem to exist on the command prompt.

fountainhead
  • 3,584
  • 1
  • 8
  • 17
  • thanks for the answer! Though it seems that `\b` does not behave like a left arrow in Jupyter: trying `print("a\b")` in Jupyter returns a blank, the `a` is erased, however, the same code in the console returns `a` as you would expect from a left arrow. It seems that the anomally comes from the `print()` function when executed in Jupyter. – Tofi Mar 31 '19 at 12:06
  • @Tofi: You're right. To avoid misleading, I should probably edit my answer to include your observation. Hope you don't mind. – fountainhead Mar 31 '19 at 12:56
  • Here is the actual code from Jupyter classic. https://github.com/jupyter/notebook/blob/ebd2b5701c36465bb3ee290797ebca09a6141347/notebook/static/base/js/utils.js#L490 It's just a couple lines of code, and is perhaps a buggy lazy implementation. And now I'm copying it over to CoCalc-Jupyter for compatibility... https://github.com/sagemathinc/cocalc/issues/5044 – William Stein Dec 01 '20 at 01:13