Show a custom value next to the bar¶
When you scan a log, the number of errors matters alongside the number
of records inspected. A Variable widget displays the error count
while the percentage tracks the scan:
"""Count errors while scanning log records with a Variable widget.
The bar counts inspected records. The named variable counts only the
records that contain an error, so the two readings describe different
parts of the same job.
"""
import time
import progressbar
from progressbar.widgets import WidgetBase
RECORDS: list[str] = [
'INFO request received',
'INFO cache hit',
'ERROR request timed out',
'INFO response sent',
'INFO connection closed',
] * 20
def main() -> None:
widgets: list[str | WidgetBase] = [
progressbar.Variable('errors', format='Errors: {value:2.0f}'),
' | Scanned ',
progressbar.Percentage(),
' ',
progressbar.Bar(),
]
errors: int = 0
bar: progressbar.ProgressBar
step: int
record: str
with progressbar.ProgressBar(
max_value=len(RECORDS), widgets=widgets, variables={'errors': 0}
) as bar:
for step, record in enumerate(RECORDS, start=1):
errors += record.startswith('ERROR')
time.sleep(0.02)
bar.update(step, errors=errors)
if __name__ == '__main__':
main()
Variable('errors') reads the errors= keyword passed to
bar.update(). The example increments that count only when a record
starts with ERROR. The scan finishes at 100% with 20 errors found
among 100 records. Placing the count first keeps it beside the scan
percentage as the bar stretches to fill the remaining width.
variables={'errors': 0} supplies the initial reading. Without an
initial value, the bar registers a placeholder for each Variable
in its widget list and displays dashes until the first update.
Older code may import DynamicMessage. It is a plain subclass of
Variable, kept for compatibility, and behaves identically. Use
Variable in new code.