I have a long-running script that loops over rows in a database. Every so often I'd like it to print how many rows it's processed, but without creating a new line each time. This is essentially what I have:
import sys
mystr = "{} rows complete\r"
for i in range(0, 100):
if i % 10 == 0:
sys.stdout.write(mystr.format(i))
sys.stdout.flush()
When I run this (on Python 2.7.5 64-bit, Windows) I get:
0 rows complete
10 rows complete
20 rows complete
...
100 rows complete
Can anyone think of why the carriage return isn't working? I've seen some similar questions here about Python and \r, but all the answers say to include sys.stdout.flush(), which I have.
Using \r is probably the correct way to go here, but the behaviour depends very much on how the text is being output. Not all terminals will respect a bare carriage return:
cmd.exe and powershell.exe should both output the text the way you expect (Powershell ISE doesn't but that's a red herring here).
Python's own idle will ignore the carriage return, all output comes on one long line.
As you noted, your own editor's command window also ignores \r.
Also, if you try from an interactive window you also get some numbers output at the end of each line: that's because the interactive windows helpfully outputs the result of the call to sys.stdout.flush().
Related
I wanted to learn command line programming using Python.
I saw a to-do challenge on the internet and started to work on it by learning from the web. The challenge is to create a command line interface of a to-do app.
The challenge is titled CoronaSafe Engineering Fellowship Test Problem. Here is the challenge material on Google Drive: https://drive.google.com/drive/folders/1SyLcxnEBNRecIyFAuL5kZqSg8Dw4xnTG?usp=sharing
and there is a GitHub project at https://github.com/nseadlc-2020/package-todo-cli-task/
In the README.md I was instructed to create symbolic link for the batch file todo.bat with the name todo. Now, my first condition is that, when the symbolic link is called from the command prompt without any arguments, it must print some usage tips for the program. Finally, I have to use the npm test command to test the execution.
At the very beginning I got this trouble, whenever I use a print statement, I see a dot • at the end of every string which ends with a new line. For instance,
import sys
import random
args = sys.argv[1:]
if len(args) == 0:
print('Usage :-', end='\n')
print('$ ./todo help # Show usage', end='')
The above statements when executed without arguments gives the output,
Usage :-.
$ ./todo help # Show usage
Here, I noticed that for the first print statement ends with a newline, the string ends with what looks like a middle dot (•). Whereas, for the second print statement since I override the end parameter with an empty string, no newline character was output, and so the dot is not printed. See the screen shot:
What's wrong, and how can I pass the test? My program does not print a middle dot at all.
The problem seems to be squarely inside the todo.test.js file.
In brief, Windows and Unix-like platforms have different line ending conventions (printing a line in Windows adds two control characters at the end, whilst on Unix-like systems only one is printed) and it looks like the test suite is only prepared to cope with results from Unix-like systems.
Try forcing your Python to only print Unix line feeds, or switch to a free Unix-like system for running the tests.
Alternatively, rename todo.test.js and replace it with a copy with DOS line feeds. In many Windows text editors, you should be able to simply open the file as a Unix text file, then "Save As..." and select Windows text file (maybe select "ANSI" if it offers that, though the term is horribly wrong and they should know better); see e.g. Windows command to convert Unix line endings? for many alternative solutions (many of which vividly illustrate some of the other issues with Windows; proceed with caution).
This seems to be a known issue, as noted in the README.md you shared: https://github.com/nseadlc-2020/package-todo-cli-task/issues/12 (though it imprecisely labels this as "newline UTF encoding issues"; the problem has nothing to do with UTF-8 or UTF-16).
See also the proposed duplicate Line endings (also known as Newlines) in JS strings
I had exactly the same problem.
I replaced:
print(variable_name) # Or print("Your text here")
With:
sys.stdout.buffer.write(variable_name.encode('utf-8')) # To sys.stdout.buffer.write("Your text here".encode('utf-8'))
Now it worked fine in windows.
First write your help string like this
help_string='Usage :-\n$ ./task add 2 hello world # Add a new item with priority 2 and text "hello world" to the list\n$ ./task ls # Show incomplete priority list items sorted by priority in ascending order\n$ ./task del INDEX # Delete the incomplete item with the given index\n$ ./task done INDEX # Mark the incomplete item with the given index as complete\n$ ./task help # Show usage\n$ ./task report # Statistics'
Then print it on the console using
sys.stdout.buffer.write(help_string.encode('utf8'))
This problem occurs due to differences in encoding type of windows and npm tests. Also make sure to avoid any spaces after or before "\n".
Why have multiple prints,when python prints can incorporate new line without having to declare separately, follow example below:
print("Usage :- \n$ ./todo help #Show usage")
Output:
Usage :-
$ ./todo help #Show usage
I am using '\r' in print function in python 2.7. It works fine in terminal but not in terminator.
For example:
I am using a decrement counter which decrements from n to 0. In the Terminal, the count values are updated at the same line while in terminator, it count values get printed on new line. I am using terminator for various reasons such as its advanced features like tab partitioning etc. Below is the code snapshot
import sys
import time
if __name__ == "__main__":
sleep_time_in_sec = 15
time_to_go_back_mns = 10
for remaining in range(sleep_time_in_sec, -1, -1):
sys.stdout.write("\r")
sys.stdout.write(
"{:2d} seconds remaining to read last {:2d} minutes of data and perform prediction .....".format(remaining,
time_to_go_back_mns))
sys.stdout.flush()
time.sleep(1)
Can someone please suggest a fix
Simply place the \r at the end of your write statement like so:
sys.stdout.write(
"{:2d} seconds remaining to read last {:2d} minutes of data and perform prediction .....\r".format(remaining,
time_to_go_back_mns))
New data will then overwrite the line, you can use flush() to clear the line before writing to it again:
sys.stdout.flush()
Make sure that on the terminator side of things your profile settings are clean. Be sure to check out the compatibility tab as it mentions weird application behaviour.
note that carriage return stops functioning if the terminal size is too small. It will only return to the first character of the LAST line
Original answer
\r actually means "carriage return" whereas \n is a line feed.
In Linux (Unix) you'd usually use either a \n or \r\n.
So if your goal is to go to a new line you should use \n instead.
The reason it might work in the "terminal" (whichever one that might be) is because some terminals (notably gnome's terminal) catches the \r and treats it as a \r\n.
The answer for this post goes to #Rick van Lieshout.
In my case, I was using multiple tabs in the same window as a result of which \r was not working. It worked fine when I used it in a separate window or a tab with full horizontal width.
This question already has answers here:
Python, writing multi line code in IDLE
(7 answers)
Closed 6 years ago.
I just picked up a basic book today on programming. The coding language is Python and I have only been trying this out for a few hours but I'm already stuck, because I can't figure out how to write multiple lines of code. For example, when I write print("one") and then hit enter, it just runs it and prints the word, one. How can I have it print the word, one, and then the word, two, on the line below it? Also, when I hit tab it just moves over 4 spaces, or so. I can't figure out how to have it not run the first command, and just give me '>>>' on the next line. So I guess what I'm asking is: What keystrokes do I need to use to get something like:
>>> print("one")
>>> print("two")
Thanks so much!
(Sorry for such a basic question, but I'm totally confused on this one.)
The Python REPL automatically executes each command as soon as it is completely typed in. This is why it is called a "read-eval-print loop". It accepts one input, evaluates it, and then prints the result.
If you want to execute two complete commands at once, you can put a semicolon between them, like this:
print("one"); print("two")
I said "completely typed in" above, because some commands inherently require multiple lines, so Python must accept several lines of input before the command is "completely typed in". Three types of command work like this: flow-control commands (def, while, if, for, etc., which apply to several indented lines below them), multiline expressions (calculations inside parentheses or brackets), or statements that use a backslash (\) at the end of the line to indicate that it is continued on the next line. So if you type in any of the blocks below, Python will wait until the block is completely finished before evaluating it.
if 1 + 1 == 2:
print "True"
else:
print "False"
print(
1 + 1
)
print \
1 + 1
You could also combine these two strategies and type something like this:
print("one"); \
print("two")
Python will wait for both commands to be typed and then run them both at once. But I've never seen anyone write code that way.
Alternatively, you could type several commands together in a different text editor, and then paste them into the Python REPL, e.g., copy and paste the following into your REPL (but you will get results printed between the commands):
print("one")
print("two")
Alternatively, you can probably get almost exactly the behavior you were originally expecting by using a different interface to Python. The IPython Notebook is a good choice, or you could try the Spyder or PyCharm editors, which let you select a few lines of code and run them.
Or, if you have a longer script that you want to run all at once, the best option is to type it up in a text file (e.g., script.py), and then tell python to run it, e.g., type python script.py from a system command prompt (not the Python interpreter), or press F5 in the IDLE editor.
One thing you may want to try is writing your code in a file, say learning.py, and then running that file on the command line with python learning.py.
The best way to get better support for multi line commands in python with a "console" feel is to use ipython qtconsole, or Jupyter qtconsole as its now called: http://jupyter.org/qtconsole/stable/. When using qtconsole, hitting Ctrl-Enter will delay the command from running even if it's not a complex block. You can keep hitting Ctrl-Enter as many times as you want, and then hit Enter to run them all. Hitting up arrow will then bring up the whole block again to edit, cleanly indented unlike the regular ipython console.
Note: this is not ipython notebook, nor the regular ipython console, but a separate thing from either using the same kernel. The qtconsole has some other nice things like better syntax highlighting and inline plotting compared to the terminal.
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.
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.