\r to update output not functioning as demonstrated - python-3.x

I'm trying to create a loading text that alternates between "Loading", "Loading.", "Loading..", "Loading...", and "Loading...." while updating the previous entry. I found similar situations online that use either sys.stdout or a \r end to the print function but have had no luck with either
The code i'm using is:
import time
tick = 0
while True:
print("Loading" + "." * tick, end="\r")
if tick < 4:
tick += 1
time.sleep(0.4)
else:
tick = 0
The output I'm getting is:
LoadingLoading.Loading..Loading...Loading....LoadingLoading.Loading..Loading...
until I force quit the execution. i haven't seen the problem mentioned in other threads but if anyone has any idea what might be causing the issue I'd be VERY grateful.

Depending on your platform you need both a carriage return \r and a newline \n or just a newline. Generally, I have found you can just do \r\n
Also depending on if you want the entire screen to clear in between "loading"s you might have to call the system call (and this differs based on platform) to clear the screen in between "loading"s being printed. This would negate the need to call \r\n because each time you print it is to a fresh console window.
You can look here for how to do this.

Related

Why does my code run successfully but give not output?

I am new to python. I am trying to open a text file with name 'P' and show the lines as an output. I wrote the code below, and it runs but not output. Why is this so?
with open('/Users/LENOVO/Desktop/P.txt','rt') as a_file:
for lines in a_file.readlines():
print(lines,ends='')`
because your print contains end=""
usually the \n is used to flush the output.
if you want to force it to flush the buffer (so to print it without the \n) you can add the flush option :
print(lines,end='', flush=True)
But maybe you just want to remove the end keyword:
print(lines)
When to use end=''?
When you use the end parameter you replace the usual \n (carret return) by something else, that is useful if you want to display a série of things next to each other without going next line everytime. (for instance if you want to print a dot . or x for each call to a function that you're calling in a loop for a big number of times.
And yes it should be end and not ends
See reference here :
https://www.w3schools.com/python/ref_func_print.asp
I do not know where you got ends='' from, but if you remove it, it produces an output.
I also figured I would also add that you are most likely referring to end, this will essentially just replace the \n which is the default value with whatever you wish.

Is there an end= equivalent for inputs?

So as I'm sure you know there's a specific operator for print() functions called end.
#as an example
print('BOB', end='-')
#would output
BOB-
So is there something like this for inputs? For example, if I wanted to have an input that would look something like this:
Input here
►
-------------------------------------------------------
And have the input at the ► and be inside the dashes using something like
x = input('Input here\n►', end='-------')
Would there be some equivalent?
EDIT:
Just to be clear, everything will be printed at the same time. The input would just be on the line marked with the ►, and the ---- would be printed below it, but at the SAME time. This means that the input would be "enclosed" by the ---.
Also, there has been a comment about curses - can you please clarify on this?
Not exactly what you want, but if the --- (or ___) can also be on the same line, you could use an input prompt with \r:
input("__________\r> ")
This means: print 10 _, then go back \r to the beginning of the line, print > overwriting the first two _, then capture the input, overwriting more _. This shows the input prompt > ________. After typing some chars: > test____. Captured input: 'test'
For more complex input forms, you should consider using curses.
When using basic console IO, once a line has been ended with a newline, it's gone and can't be edited. You can't move the cursor up to do print anything above that last line, only add on a new line below.
That means that without using a specialized "console graphics" library like curses (as tobias_k suggests), you pretty much can't do what you're asking. You can mess around a little with the contents of the last line (overwriting text you've already written there), but you can't write to any line other than the last one.
To understand why console IO works this way, you should know that very early computers didn't have screens. Instead, their console output was directly printed out one line at a time on paper. While some line printers could print several characters on the same spot (to get effects line strikethrough or underline), you couldn't unprint anything once it was on the paper. Furthermore, the paper feed only worked in one direction. Once you had sent a newline character that told the printer to advance the paper, you couldn't go back to an old line again.
I believe this would solve your problem:
print(f">>> {input()} ------")
OR
print(f"{input(">>>")} ------")
F-strings are quite useful when it comes to printing text + variables.

updating multiple lines without making a new line python [duplicate]

I would like to overwrite something on a line above in a serial console. Is there a character that allows me to move up?
Most terminals understand ANSI escape codes. The relevant codes for this use case:
"\033[F" – move cursor to the beginning of the previous line
"\033[A" – move cursor up one line
Example (Python):
print("\033[FMy text overwriting the previous line.")
No, not really easily, for that you'd have to use something like the curses library, especially if you want to have more control over cursor placement and do more things programatically.
Here's a link for the Python docs on Programming with Curses, and this short tutorial/example might be of interest too.
I just found this note in the docs in case you are using Windows:
No one has made a Windows port of the curses module. On a Windows
platform, try the Console module written by Fredrik Lundh. The Console
module provides cursor-addressable text output, plus full support for
mouse and keyboard input, and is available from
http://effbot.org/zone/console-index.htm.
I believe for C++ there is the NCurses library, the linked page has a section on moving the cursor if you want to poke around with C++. Also there's the NCurses Programming HowTo.
Long time ago I used the curses library with C quite successfully.
Update:
I missed the part about running this on a terminal/serially, for that the ANSI escape sequence, especially for a simple task like yours, will be easiest and I agree with #SvenMarnach solution for this.
for i in range(10):
print("Loading" + "." * i)
doSomeTimeConsumingProcessing()
sys.stdout.write("\033[F") # Cursor up one lin
Try this in Python and replace doSomeTimeConsumingProcessing() with any routine needed, and hope it helps
Carriage return can be used to go to the beginning of line, and ANSI code ESC A ("\033[A") can bring you up a line. This works on Linux. It can work on Windows by using the colorama package to enable ANSI codes:
import time
import sys
import colorama
colorama.init()
print("Line 1")
time.sleep(1)
print("Line 2")
time.sleep(1)
print("Line 3 (no eol)", end="")
sys.stdout.flush()
time.sleep(1)
print("\rLine 3 the sequel")
time.sleep(1)
print("\033[ALine 3 the second sequel")
time.sleep(1)
print("\033[A\033[A\033[ALine 1 the sequel")
time.sleep(1)
print() # skip two lines so that lines 2 and 3 don't get overwritten by the next console prompt
print()
Output:
> python3 multiline.py
Line 1 the sequel
Line 2
Line 3 the second sequel
>
Under the hood, colorama presumably enables Console Virtual Terminal Sequences
using SetConsoleMode.
I may be wrong but :
#include <windows.h>
void gotoxy ( int column, int line )
{
COORD coord;
coord.X = column;
coord.Y = line;
SetConsoleCursorPosition(
GetStdHandle( STD_OUTPUT_HANDLE ),
coord
);
}
in windows standard console.
A simple way based on #Sven Marnach answer:
print(f'\033[A\rxxx')
\033[A: Move cursor one line up.
\r: Move the cursor to the beginning of the line.
xxx: The string to be printed. {xxx} if it is a variable
If you have some extra characters from the previous line after your string, overwrite them with white space, depending on the length of the previous line. Below I added 10 white spaces.
print(f'\033[A\rxxx{' '* 10}')

Python '\r' print on the same line but won't erase the previous text

I am trying to print the report for each iteration. Since each iteration takes a really long time to run, therefore, I use print together with end="\r" to show the current item being processed.
Here's the dummy code:
import time
y = list(range(50))
print("epoch\ttrain loss\ttest loss\ttrain avg\ttest avg\ttime\tutime")
for e in range(10):
for i in range(50):
print("training {}/{} batches".format(i,50), end = '\r')
time.sleep(0.05)
print('{}\t{:2f}\t{:2f}\t{:2f}\t{:2f}\t{:2.1f}\t{:2.1f}'.format(y[0]+e,y[1]+e,y[2]+e,y[3]+e,y[4]+e,y[5]+e,y[6]+e))
Expected Result
This is my expected result, where the progress information is completely erased after each iteration. (I am running it in Jupyter notebook, and it looks fine)
The Result that I am getting
However, when I run it on linux terminal, the progress information is not completely erased, and the result is overlaying on top of the progress.
Why is it so? How to solve it?
\r simply moves the cursor back to the beginning of the current line. Anything printed after the \r is printed "on top of" the content previously there. On a real printer/teletype this would be literally true, with two characters getting printed in the same position ("overstruck"). On a terminal, the new characters replace the old ones (but only in positions that you actually write to).
You can take advantage of this behavior of terminals by printing spaces. You need at least as many spaces as the content you want to erase, but not enough to make the terminal wrap to the next line (this may be impossible if the line was printed all the way to the last character).
In your case, you know that the line won't be more than 22 characters long, so you could use end='\r \r' (go back to the beginning of the line, print 22 blanks, then go back to the beginning of the line again).
\r option will set (move) the cursor to start. It will not clear the text.
You have to make sure your printed data has enough space to overwrite the previous printed data or be of the same length since just moving to the same line would not automatically clear the previous contents.

How do I erase printed characters in a console application(Linux)?

I am creating a small console app that needs a progress bar. Something like...
Conversion: 175/348 Seconds |========== | 50%
My question is, how do you erase characters already printed to the console? When I reach the 51st percentage, I have to erase this line from the console and insert a new line. In my current solution, this is what happens...
Conversion: 175/348 Seconds |========== | 50%
Conversion: 179/348 Seconds |========== | 52%
Conversion: 183/348 Seconds |========== | 54%
Conversion: 187/348 Seconds |=========== | 56%
Code I use is...
print "Conversion: $converted_seconds/$total_time Seconds $progress_bar $converted_percentage%\n";
I am doing this in Linux using PHP(only I will use the app - so please excuse the language choice). So, the solution should work on the Linux platform - but if you have a solution that's cross platform, that would be preferable.
I don't think you need to apologize for the language choice. PHP is a great language for console applications.
Try this out:
<?php
for( $i=0;$i<10;$i++){
print "$i \r";
sleep(1);
}
?>
The "\r" will overwrite the line with the new text. To make a new line you can just use "\n", but I'm guessing you already knew that.
Hope this helps! I know this works in Linux, but I don't know if it works in Windows or other operating systems.
To erase a previously printed character you have three options:
echo chr(8) . " "; echoes the back character, and will move the cursor back one place, and the space then overwrites the character. You can use chr(8) multiple times in a row to move back multiple characters.
echo "\r"; will return the cursor to the start of the current line. You can now replace the line with new text.
The third option is to set the line and column of the cursor position using ANSI escape codes, then print the replacement characters. It might not work with all terminals:
function movecursor($line, $column){
echo "\033[{$line};{$column}H";
}
\r did the trick.
For future reference, \b does not work in PHP in Linux. I was curious - so I did a couple of experiments in other languages as well(I did this in Linux - I don't know if the result will be the same in Windows/Mac)..
\b Works in...
Perl
Ruby
Tcl - with code puts -nonewline "Hello\b"
\b Doesn't work in
PHP - the code print "Hello\b"; prints out Hello\b
Python - code print "Hello\b" prints out Hello<new line> . Same result with print "Hello\b",
I'm not sure if it's the same in Linux but in Windows console apps you can print \r and the cursor will return to the first left position of the line allowing you to overwrite all the characters to the right.
You can use \b to move back a single character but since you're going to be updating your progress bar \r would be simpler to use than printing \b x number of times.
This seems to be pretty old topic but I will drop my 5 into.
for ($i; $i<_POSITION_; $i--) {
echo "\010"; //issue backspace
}
Found this on the internet some time ago, unfortunately don't remember where. So all credits goes to original author.
to erase a previously printed character, I print a backspace after it:
print "a"
print "\b"
will print nothing (actually it will print and then a backspace, but you probably won't notice it)

Resources