Coverage for /var/devmt/py/utils4_1.8.0/utils4/progressbar.py: 100%
14 statements
« prev ^ index » next coverage.py v7.6.9, created at 2025-08-26 21:39 +0100
« prev ^ index » next coverage.py v7.6.9, created at 2025-08-26 21:39 +0100
1# -*- coding: utf-8 -*-
2"""
3:Purpose: This is a small class module which provides access to a
4 simple console progress bar.
6:Developer: J Berendt
7:Email: support@s3dev.uk
9:Comments: n/a
11:Example: For a simple usage example, refer to the :class:`~ProgressBar`
12 class docstring.
14"""
16import sys
19class ProgressBar:
20 """Implement a console progress bar into a processing loop.
22 Args:
23 total_values (int, optional): Total number of iterations.
24 Defaults to 25.
25 bar_len (int, optional): Complete length of the progress bar, in chars.
26 Defaults to 25
27 symbol (str, optional): The symbol which is used to track progress.
28 Defaults to ``'.'``.
29 color (str, optional): Colour of the progress bar; where only the first
30 letter of the colour is required.
31 Options are: red, green, yellow, blue, magenta, cyan, white.
32 Defaults to 'w' (white).
34 :Design:
35 This is a simple console progress bar which should be called
36 **inside** a processing loop.
38 On instantiation, you can pass in the bar colour, length and
39 symbol parameters if you want to configure the appearance a
40 little bit.
42 :Colour Options:
43 red, green, yellow, blue, magenta, cyan, white
45 :Example:
46 You might implement the progress bar in a loop like this::
48 >>> import time
49 >>> from utils4.progressbar import ProgressBar
51 >>> pb = ProgressBar(total_values=25,
52 bar_len=25,
53 symbol='#',
54 color='red')
56 >>> for i range(26):
57 >>> # < some processing >
58 >>> pb.update_progress(current=i)
59 >>> # Optional pause to see updates.
60 >>> time.sleep(.1)
62 Processing 25 of 25 [ ......................... ] 100% Complete
64 """
66 def __init__(self, total_values: int=25, bar_len: int=25, symbol: str='.', color: str='w'):
67 """Progress bar class initialiser."""
68 self._total = total_values
69 self._bar_len = bar_len
70 self._symbol = symbol
71 self._color = color
72 self._len = len(str(self._total))
73 self._rst = '\x1b[0m'
74 self._clr = self._getcolor()
76 def update_progress(self, current: int): # pragma: nocover
77 """Incrementally update the progress bar.
79 Args:
80 current (int): Index value for the current iteration.
81 This value is compared against the initialised ``total_values``
82 parameter to determine the current position in the overall
83 progress.
85 :Example:
87 Refer to the :class:`~ProgressBar` class docstring.
89 """
90 # Calculate percent complete.
91 percent = float(current) / self._total
92 # Number of ticks.
93 ticks = self._symbol * int(round(percent * self._bar_len))
94 # Number of space placeholders.
95 spaces = ' ' * (self._bar_len - len(ticks))
96 msg = (f'{self._clr}'
97 f'\rProcessing {str(current).zfill(self._len)} of {self._total} [ {ticks+spaces} ] '
98 f'{percent*100:.0f}% Complete{self._rst}')
99 sys.stdout.write(msg)
100 sys.stdout.flush()
102 def _getcolor(self) -> str:
103 """Create ANSI colour escape sequence to user's colour.
105 Returns:
106 str: ANSI escape sequence string for the user's colour.
108 """
109 clrs = {'r': 31, 'g': 32, 'y': 33, 'b': 34, 'm': 35, 'c': 36, 'w': 37}
110 seq = f'\033[{clrs.get(self._color[0])};40m'
111 return seq