(2023.9.4)更新:
- 计时、估计剩余时间(ETA,Expected Time of Arrival);
- 支持手写的、无实现
__len__
的 generator; - 支持嵌套使用。
代码见 iTomxy/ml-template/utils/misc.py/prog_bar
。例程:
# import time
# from utils import prog_bar
# 训练数据
X = ([1, 2], [3, 4], [5, 6], [7, 8])
# 手写 generator,无 `__len__` 也能用
def _generator(_X):
for _x in _X:
yield _x
print("before prog_bar")
# 嵌套循环,嵌套用 prog_bar 只打印最内层的 progress bar
for epoch in prog_bar("abc", "Epoch"): # string
print('Epoch:', epoch)
for i in prog_bar(range(15, 7, -2), "range"): # range
print("\trange:", i)
time.sleep(0.5)
for x in prog_bar(X, "X"): # 数据
print("\t\tX:", x)
time.sleep(0.2)
for x in prog_bar(_generator(X), "iterator"): # generator
print("\titerator:", x)
time.sleep(1)
print("after prog_bar:")
类似 tqdm[1] 的东西,效果:
- 打印
[ <NOW> / <TOTAL> ]
式简易进度条。支持自定义前缀信息,形如:<MESSAGE>: [ <NOW> / <TOTAL> ]
; - 用法类似 tqdm,可套在 range、list、tuple、numpy.ndarray 上面用 for 遍历。手写的 generator 会报错:
TypeError: object of type 'generator' has no len()
,不支持,但 tqdm 支持。
原理就是不换行、并用 \r
重写行。
Code & Example
import time
import numpy as np
from collections.abc import Iterable
def prog_bar(iter_obj, prefix=None):
"""simple progress bar (better NOT to use `print` inside)
Input:
- iter_obj: iter_obj: range, tuple, list, numpy.ndarray
- prefix: str, some message to show
Ref:
- https://stackoverflow.com/questions/3002085/how-to-print-out-status-bar-and-percentage
"""
if isinstance(iter_obj, range):
_start, _stop, _step = iter_obj.start, iter_obj.stop, iter_obj.step
elif isinstance(iter_obj, Iterable):
_start, _stop, _step = 0, len(iter_obj), 1
else:
raise NotImplemented
n_digit = len(str(_stop))
if prefix != None:
template = "\r{}: [ %*d / %*d ]".format(prefix)
else:
template = "\r[ %*d / %*d ]"
print("", end="")
print(template % (n_digit, _start, n_digit, _stop), end="")
for i, x in enumerate(iter_obj):
yield x
print(template % (n_digit, _start + (i + 1) * _step, n_digit, _stop), end="")
print(template % (n_digit, _stop, n_digit, _stop))#, end="")
print("abcd")
for i in prog_bar(range(12, 103, 10)):
time.sleep(1)
print("efg")
print("hijk")
for x in prog_bar([1, 2, 3], "list"):
time.sleep(1)
print("lmn")
print("opq")
for x in prog_bar((4, 5, 6), "tuple"):
time.sleep(1)
print("rst")
print("uvw")
for x in prog_bar(np.array([[7, 8, 9], [10, 11, 12]]), "np.ndarray"):
time.sleep(1)
print("xyz")