Step 2: Update a ProgressBar explicitly¶
Not every loop hands you a clean iterable to wrap – sometimes you need to
decide for yourself when and where progress has moved on. This step drops
the wrapper from the previous step and drives a ProgressBar by hand.
"""The explicit form: build a `ProgressBar` and `update()` it yourself.
`progressbar.progressbar()` from the previous step is a shortcut over
this. Use a `ProgressBar` as a context manager and call `update()` with the
new value wherever your own loop happens to be, instead of handing the
loop itself to a wrapper.
"""
import time
import progressbar
def main() -> None:
with progressbar.ProgressBar() as bar:
for i in range(100):
time.sleep(0.01)
bar.update(i + 1)
if __name__ == '__main__':
main()
The previous step gave range(100) to progressbar.progressbar() and
let it manage everything. Here, the loop opens the bar as a context
manager with with progressbar.ProgressBar() as bar: and, on each pass
through its own for loop, calls bar.update(i + 1) to report the
new value itself. The with block starts the bar on entry and finishes
it on exit, just as progressbar.progressbar() did implicitly in step
1. The difference is that this code decides when update() is called,
so it works just as well when progress doesn’t come from iterating a
sequence at all.