Apr-21-2021, 07:01 AM
(This post was last modified: Jun-17-2021, 11:59 AM by MvGulik.
Edit Reason: Updated to third version, +minor bug fix.
)
A little simple pure text based progress bar.
In my case the output pane will not do a true carriage return(\r), but will do an additional line feed (\r => \r\n).
(The picked Pbar characters are related to the proportional font my output pane is using)
+(Updated to second version. Behaving overall as intended.)
+(Updated to third version. Behaving finally as intended. +(minor bug fix).)
(Might not truly classify as simple anymore. Well, code wise I guess. ... Was fun little personal project.)
In my case the output pane will not do a true carriage return(\r), but will do an additional line feed (\r => \r\n).
(The picked Pbar characters are related to the proportional font my output pane is using)
+(Updated to second version. Behaving overall as intended.)
+(Updated to third version. Behaving finally as intended. +(minor bug fix).)
(Might not truly classify as simple anymore. Well, code wise I guess. ... Was fun little personal project.)
class Pbar(): def __init__(self, loops, title='', barlen=80, chr1='~', chr2='#'): if isinstance(loops, int): pass elif isinstance(loops, float): loops = int(loops) else: loops = len(loops) if not isinstance(barlen, int): barlen = int(barlen) self._loops = loops if loops > 1 else 1 self._title = str(title) if str(title) else '' self._barlen = barlen if barlen > 11 else 11 ## True minimale bar length is "ciel(set-value/2)". Or 6 when set to 11 or 12 for example. if self._loops < self._barlen: self._step = self._barlen//self._loops self._barlen = self._loops * self._step else: self._step = 1 self._loops -= 0 if self._title: self._title = '[ ' + self._title + ' ]' self._chr1 = chr1[:1] self._chr2 = chr2[:1] self._count = 0 self._progress = 0 self._done = False self._pre_bar() def _pre_bar(self): if self._title: ## General title centering for proportional fonts. ## For monospaced fonts "offset*1" should do the trick. offset = self._barlen//2 - len(self._title)//2 print(''.rjust(offset*3, ' '), self._title) print(''.rjust(self._barlen, self._chr1)) def loop(self): if self._done: return self._count += 1 new_progress = int(round(self._count / self._loops * self._barlen)) if new_progress > self._progress: self._progress = new_progress print(''.rjust(self._step, self._chr2), end='') def done(self): self._done = True print() print() def pbar_example_run(): import time import random for x in range(6): barlen = int(random.random() * 15) * x loop = int(random.random() * 23) * x + 1 title = 'Test run: Loop ' + str(loop) + ' over Bar ' + str(barlen) + '.' _time = 1/loop if loop > 0 else 1 pbar = Pbar(loop, title=title , barlen=barlen) for i in range(loop): time.sleep(_time) pbar.loop() pbar.done() if (__name__ == "__main__"): pbar_example_run()
Output: [ Test run: Loop 111 over Bar 6. ]
~~~~~~~~~~~
###########
[ Test run: Loop 6 over Bar 111. ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
############################################################################################################
(Python 3.8.5)