How do I write output in same place on the console?
Question:
I am new to python and am writing some scripts to automate downloading files from FTP servers, etc. I want to show the progress of the download, but I want it to stay in the same position, such as:
output:
Downloading File FooFile.txt [47%]
I’m trying to avoid something like this:
Downloading File FooFile.txt [47%]
Downloading File FooFile.txt [48%]
Downloading File FooFile.txt [49%]
How should I go about doing this?
Duplicate: How can I print over the current line in a command line application?
Answers:
Print the backspace character b
several times, and then overwrite the old number with the new number.
Use a terminal-handling library like the curses module:
The curses module provides an interface to the curses library, the de-facto standard for portable advanced terminal handling.
You can also use the carriage return:
sys.stdout.write("Download progress: %d%% r" % (progress) )
sys.stdout.flush()
Python 2
I like the following:
print 'Downloading File FooFile.txt [%d%%]r'%i,
Demo:
import time
for i in range(100):
time.sleep(0.1)
print 'Downloading File FooFile.txt [%d%%]r'%i,
Python 3
print('Downloading File FooFile.txt [%d%%]r'%i, end="")
Demo:
import time
for i in range(100):
time.sleep(0.1)
print('Downloading File FooFile.txt [%d%%]r'%i, end="")
PyCharm Debugger Console with Python 3
# On PyCharm Debugger console, r needs to come before the text.
# Otherwise, the text may not appear at all, or appear inconsistently.
# tested on PyCharm 2019.3, Python 3.6
import time
print('Start.')
for i in range(100):
time.sleep(0.02)
print('rDownloading File FooFile.txt [%d%%]'%i, end="")
print('nDone.')
#kinda like the one above but better :P
from __future__ import print_function
from time import sleep
for i in range(101):
str1="Downloading File FooFile.txt [{}%]".format(i)
back="b"*len(str1)
print(str1, end="")
sleep(0.1)
print(back, end="")
A neat solution that has been working for me is:
from __future__ import print_function
import sys
for i in range(10**6):
perc = float(i) / 10**6 * 100
print(">>> Download is {}% complete ".format(perc), end='r')
sys.stdout.flush()
print("")
The sys.stdout.flush
is important otherwise it gets really clunky and the print("")
on for loop exit is also important.
UPDATE: As mentioned in the comments, print
also has a flush
argument. So the following will also work:
from __future__ import print_function
for i in range(10**6):
perc = float(i) / 10**6 * 100
print(">>> Download is {}% complete ".format(perc), end='r', flush=True)
print("")
For Python 3xx:
import time
for i in range(10):
time.sleep(0.2)
print ("r Loading... {}".format(i)+str(i), end="")
x="A Sting {}"
for i in range(0,1000000):
y=list(x.format(i))
print(x.format(i),end="")
for j in range(0,len(y)):
print("b",end="")
In python 3 the function print can get many arguments.
the full signature of the function print is:
print(args*, sep=' ', end='n', file=sys.stdout, flush=False)
when sep
is the separator of the arguments from args*
, end
is how to end the printed line (‘n means a new line) file is to where print the output (stdout is the consul) and flush is if to clean the buffer.
Usage Example
import sys
a = 'A'
b = 0
c = [1, 2, 3]
print(a, b, c, 4, sep=' * ', end='n' + ('-' * 21), file=sys.stdout, flush=True)
Output
A * 0 * [1, 2, 3] * 4
---------------------
In python there are many ways to format string and even a built in formatted string type.
How to format string
- the
format()
function. (some examples)
- Formatted String Literals or in the common name f-strings.
- format using % (more about this)
Examples
name = 'my_name'
>>> print('my name is: {}'.format(name))
my name is: my_name
# or
>>> print('my name is: {user_name}'.format(user_name=name))
my name is: my_name
# or
>>> print('my name is: {0}'.format(name))
my name is: my_name
# or using f-strings
>>> print(f'my name is: {name}')
my name is: my_name
# or formatting with %
>>> print('my name is: %s' % name)
my name is: my_name
I am new to python and am writing some scripts to automate downloading files from FTP servers, etc. I want to show the progress of the download, but I want it to stay in the same position, such as:
output:
Downloading File FooFile.txt [47%]
I’m trying to avoid something like this:
Downloading File FooFile.txt [47%]
Downloading File FooFile.txt [48%]
Downloading File FooFile.txt [49%]
How should I go about doing this?
Duplicate: How can I print over the current line in a command line application?
Print the backspace character b
several times, and then overwrite the old number with the new number.
Use a terminal-handling library like the curses module:
The curses module provides an interface to the curses library, the de-facto standard for portable advanced terminal handling.
You can also use the carriage return:
sys.stdout.write("Download progress: %d%% r" % (progress) )
sys.stdout.flush()
Python 2
I like the following:
print 'Downloading File FooFile.txt [%d%%]r'%i,
Demo:
import time
for i in range(100):
time.sleep(0.1)
print 'Downloading File FooFile.txt [%d%%]r'%i,
Python 3
print('Downloading File FooFile.txt [%d%%]r'%i, end="")
Demo:
import time
for i in range(100):
time.sleep(0.1)
print('Downloading File FooFile.txt [%d%%]r'%i, end="")
PyCharm Debugger Console with Python 3
# On PyCharm Debugger console, r needs to come before the text.
# Otherwise, the text may not appear at all, or appear inconsistently.
# tested on PyCharm 2019.3, Python 3.6
import time
print('Start.')
for i in range(100):
time.sleep(0.02)
print('rDownloading File FooFile.txt [%d%%]'%i, end="")
print('nDone.')
#kinda like the one above but better :P
from __future__ import print_function
from time import sleep
for i in range(101):
str1="Downloading File FooFile.txt [{}%]".format(i)
back="b"*len(str1)
print(str1, end="")
sleep(0.1)
print(back, end="")
A neat solution that has been working for me is:
from __future__ import print_function
import sys
for i in range(10**6):
perc = float(i) / 10**6 * 100
print(">>> Download is {}% complete ".format(perc), end='r')
sys.stdout.flush()
print("")
The sys.stdout.flush
is important otherwise it gets really clunky and the print("")
on for loop exit is also important.
UPDATE: As mentioned in the comments, print
also has a flush
argument. So the following will also work:
from __future__ import print_function
for i in range(10**6):
perc = float(i) / 10**6 * 100
print(">>> Download is {}% complete ".format(perc), end='r', flush=True)
print("")
For Python 3xx:
import time
for i in range(10):
time.sleep(0.2)
print ("r Loading... {}".format(i)+str(i), end="")
x="A Sting {}"
for i in range(0,1000000):
y=list(x.format(i))
print(x.format(i),end="")
for j in range(0,len(y)):
print("b",end="")
In python 3 the function print can get many arguments.
the full signature of the function print is:
print(args*, sep=' ', end='n', file=sys.stdout, flush=False)
when sep
is the separator of the arguments from args*
, end
is how to end the printed line (‘n means a new line) file is to where print the output (stdout is the consul) and flush is if to clean the buffer.
Usage Example
import sys
a = 'A'
b = 0
c = [1, 2, 3]
print(a, b, c, 4, sep=' * ', end='n' + ('-' * 21), file=sys.stdout, flush=True)
Output
A * 0 * [1, 2, 3] * 4
---------------------
In python there are many ways to format string and even a built in formatted string type.
How to format string
- the
format()
function. (some examples) - Formatted String Literals or in the common name f-strings.
- format using % (more about this)
Examples
name = 'my_name'
>>> print('my name is: {}'.format(name))
my name is: my_name
# or
>>> print('my name is: {user_name}'.format(user_name=name))
my name is: my_name
# or
>>> print('my name is: {0}'.format(name))
my name is: my_name
# or using f-strings
>>> print(f'my name is: {name}')
my name is: my_name
# or formatting with %
>>> print('my name is: %s' % name)
my name is: my_name