实现如下所示的状态栏:
[========== ] 45%
[================ ] 60%
[==========================] 100%
我想把这个打印到标准输出,并保持刷新,而不是打印到另一行。如何做到这一点?
实现如下所示的状态栏:
[========== ] 45%
[================ ] 60%
[==========================] 100%
我想把这个打印到标准输出,并保持刷新,而不是打印到另一行。如何做到这一点?
当前回答
没有一个答案能完全满足我的需求。所以我写了我自己的,如上所示。我需要的功能:
只传递步数和总步数,它就完成了计算完成百分比的困难工作。 使用60个字符,将它们分成480个“刻度”,每个刻度产生0.21%的收益。如果没有勾号,每个字符只占1.67%。 支持将标题放在前面。 行尾完成百分比可选。 可变长度的进度条,默认为60个字符或480个“刻度”。 设置进度条颜色,默认为绿色。
如何调用进度显示
调用进度显示非常简单。对于上面的样例.gif函数调用使用:
percent_complete(step, total_steps, title="Convert Markdown")
在CSV格式的Stack Exchange Data Dump中,len(rows)的total_steps约为2,500。该步骤是当前行号,因为每个Stack Exchange Markdown问答都转换为Kramdown(用于GitHub页面)。
Python代码
代码很简单,但比其他答案长一些:
def percent_complete(step, total_steps, bar_width=60, title="", print_perc=True):
import sys
# UTF-8 left blocks: 1, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8
utf_8s = ["█", "▏", "▎", "▍", "▌", "▋", "▊", "█"]
perc = 100 * float(step) / float(total_steps)
max_ticks = bar_width * 8
num_ticks = int(round(perc / 100 * max_ticks))
full_ticks = num_ticks / 8 # Number of full blocks
part_ticks = num_ticks % 8 # Size of partial block (array index)
disp = bar = "" # Blank out variables
bar += utf_8s[0] * int(full_ticks) # Add full blocks into Progress Bar
# If part_ticks is zero, then no partial block, else append part char
if part_ticks > 0:
bar += utf_8s[part_ticks]
# Pad Progress Bar with fill character
bar += "▒" * int((max_ticks/8 - float(num_ticks)/8.0))
if len(title) > 0:
disp = title + ": " # Optional title to progress display
# Print progress bar in green: https://stackoverflow.com/a/21786287/6929343
disp += "\x1b[0;32m" # Color Green
disp += bar # Progress bar to progress display
disp += "\x1b[0m" # Color Reset
if print_perc:
# If requested, append percentage complete to progress display
if perc > 100.0:
perc = 100.0 # Fix "100.04 %" rounding error
disp += " {:6.2f}".format(perc) + " %"
# Output to terminal repetitively over the same line using '\r'.
sys.stdout.write("\r" + disp)
sys.stdout.flush()
Python代码注释
以下几点:
The [ .... ] bracket placeholders requirement in the question are not necessary because there is the fill characters that serve the same purpose. This saves two extra characters to make the progress bar wider. The bar_width keyword parameter can be used depending on screen width. The default of 60 seems a good fit for most purposes. The print_perc=True keyword parameter default can be overridden by passing print_perc=False when calling the function. This would allow a longer progress bar. The title="" keyword parameter defaults to no title. Should you desire one use title="My Title" and : will automatically be added to it. When your program finishes remember to call sys.stdout.write("\r") followed by sys.stdout.flush() to clear the progress display line.
总结
这个答案比其他答案长一点,但重要的是要注意它是一个完整的解决方案,而不是需要添加更多代码的解决方案的一部分。
另一点是这个解决方案没有依赖关系,也不需要安装任何额外的东西。Python支持UTF-8字符集,不需要额外设置gnome-terminal。如果你使用的是python2.7,在shebang后面可能需要# -*- coding: utf-8 -*-。IE作为程序的第二行。
该函数可以转换为具有单独的init、update、pause(用于将调试内容打印到屏幕上)、resume和close方法的类。
这个函数是从bash脚本转换过来的:
如何将进度条添加到shell脚本?
bash脚本将显示索尼电视音量与libnotify-bin(弹出泡泡消息)每当电视音量改变。如果您对bash进度条感兴趣,请访问Stack Overflow链接。
编辑于2022年1月30日
每个角色从4个刻度改为8个刻度。 移除整块之间的间隙。 添加颜色支持。
其他回答
在这里和其他地方的一些答案的基础上,我编写了这个简单的函数,它显示一个进度条和经过/估计的剩余时间。应该在大多数基于unix的机器上运行。
import time
import sys
percent = 50.0
start = time.time()
draw_progress_bar(percent, start)
def draw_progress_bar(percent, start, barLen=20):
sys.stdout.write("\r")
progress = ""
for i in range(barLen):
if i < int(barLen * percent):
progress += "="
else:
progress += " "
elapsedTime = time.time() - start;
estimatedRemaining = int(elapsedTime * (1.0/percent) - elapsedTime)
if (percent == 1.0):
sys.stdout.write("[ %s ] %.1f%% Elapsed: %im %02is ETA: Done!\n" %
(progress, percent * 100, int(elapsedTime)/60, int(elapsedTime)%60))
sys.stdout.flush()
return
else:
sys.stdout.write("[ %s ] %.1f%% Elapsed: %im %02is ETA: %im%02is " %
(progress, percent * 100, int(elapsedTime)/60, int(elapsedTime)%60,
estimatedRemaining/60, estimatedRemaining%60))
sys.stdout.flush()
return
没有一个答案能完全满足我的需求。所以我写了我自己的,如上所示。我需要的功能:
只传递步数和总步数,它就完成了计算完成百分比的困难工作。 使用60个字符,将它们分成480个“刻度”,每个刻度产生0.21%的收益。如果没有勾号,每个字符只占1.67%。 支持将标题放在前面。 行尾完成百分比可选。 可变长度的进度条,默认为60个字符或480个“刻度”。 设置进度条颜色,默认为绿色。
如何调用进度显示
调用进度显示非常简单。对于上面的样例.gif函数调用使用:
percent_complete(step, total_steps, title="Convert Markdown")
在CSV格式的Stack Exchange Data Dump中,len(rows)的total_steps约为2,500。该步骤是当前行号,因为每个Stack Exchange Markdown问答都转换为Kramdown(用于GitHub页面)。
Python代码
代码很简单,但比其他答案长一些:
def percent_complete(step, total_steps, bar_width=60, title="", print_perc=True):
import sys
# UTF-8 left blocks: 1, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8
utf_8s = ["█", "▏", "▎", "▍", "▌", "▋", "▊", "█"]
perc = 100 * float(step) / float(total_steps)
max_ticks = bar_width * 8
num_ticks = int(round(perc / 100 * max_ticks))
full_ticks = num_ticks / 8 # Number of full blocks
part_ticks = num_ticks % 8 # Size of partial block (array index)
disp = bar = "" # Blank out variables
bar += utf_8s[0] * int(full_ticks) # Add full blocks into Progress Bar
# If part_ticks is zero, then no partial block, else append part char
if part_ticks > 0:
bar += utf_8s[part_ticks]
# Pad Progress Bar with fill character
bar += "▒" * int((max_ticks/8 - float(num_ticks)/8.0))
if len(title) > 0:
disp = title + ": " # Optional title to progress display
# Print progress bar in green: https://stackoverflow.com/a/21786287/6929343
disp += "\x1b[0;32m" # Color Green
disp += bar # Progress bar to progress display
disp += "\x1b[0m" # Color Reset
if print_perc:
# If requested, append percentage complete to progress display
if perc > 100.0:
perc = 100.0 # Fix "100.04 %" rounding error
disp += " {:6.2f}".format(perc) + " %"
# Output to terminal repetitively over the same line using '\r'.
sys.stdout.write("\r" + disp)
sys.stdout.flush()
Python代码注释
以下几点:
The [ .... ] bracket placeholders requirement in the question are not necessary because there is the fill characters that serve the same purpose. This saves two extra characters to make the progress bar wider. The bar_width keyword parameter can be used depending on screen width. The default of 60 seems a good fit for most purposes. The print_perc=True keyword parameter default can be overridden by passing print_perc=False when calling the function. This would allow a longer progress bar. The title="" keyword parameter defaults to no title. Should you desire one use title="My Title" and : will automatically be added to it. When your program finishes remember to call sys.stdout.write("\r") followed by sys.stdout.flush() to clear the progress display line.
总结
这个答案比其他答案长一点,但重要的是要注意它是一个完整的解决方案,而不是需要添加更多代码的解决方案的一部分。
另一点是这个解决方案没有依赖关系,也不需要安装任何额外的东西。Python支持UTF-8字符集,不需要额外设置gnome-terminal。如果你使用的是python2.7,在shebang后面可能需要# -*- coding: utf-8 -*-。IE作为程序的第二行。
该函数可以转换为具有单独的init、update、pause(用于将调试内容打印到屏幕上)、resume和close方法的类。
这个函数是从bash脚本转换过来的:
如何将进度条添加到shell脚本?
bash脚本将显示索尼电视音量与libnotify-bin(弹出泡泡消息)每当电视音量改变。如果您对bash进度条感兴趣,请访问Stack Overflow链接。
编辑于2022年1月30日
每个角色从4个刻度改为8个刻度。 移除整块之间的间隙。 添加颜色支持。
根据上面的答案和其他类似的关于CLI进度条的问题,我想我得到了一个普遍的答案。请登录https://stackoverflow.com/a/15860757/2254146查看。
下面是这个函数的一个副本,但是为了适合你的风格进行了修改:
import time, sys
# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
barLength = 20 # Modify this to change the length of the progress bar
status = ""
if isinstance(progress, int):
progress = float(progress)
if not isinstance(progress, float):
progress = 0
status = "error: progress var must be float\r\n"
if progress < 0:
progress = 0
status = "Halt...\r\n"
if progress >= 1:
progress = 1
status = "Done...\r\n"
block = int(round(barLength*progress))
text = "\rPercent: [{0}] {1}% {2}".format( "="*block + " "*(barLength-block), progress*100, status)
sys.stdout.write(text)
sys.stdout.flush()
看起来像
百分比:[====================]99.0%
在尝试了Mark Rushakoff的解决方案后,我今天看到了这个帖子
from time import sleep
import sys
for i in range(21):
sys.stdout.write('\r')
# the exact output you're looking for:
sys.stdout.write("[%-20s] %d%%" % ('='*i, 5*i))
sys.stdout.flush()
sleep(0.25)
我可以说这在使用python 3.4.3 64位的W7-64上工作得很好,但仅限于本机控制台。但是,当使用spyder 3.0.0dev的内置控制台时,换行符仍然/再次出现。由于我花了一些时间来弄清楚,我想在这里报告这一观察结果。
import progressbar
import time
# Function to create
def animated_marker():
widgets = ['Loading: ', progressbar.Bar('=', '[', ']', '-'), progressbar.Percentage()]
bar = progressbar.ProgressBar(max_value=200,widgets=widgets).start()
for i in range(200):
time.sleep(0.1)
bar.update(i+1)
bar.finish()
# Driver's code
animated_marker()