A progress bar which can print the progress.
| 23 | |
| 24 | |
| 25 | class ProgressBar: |
| 26 | """A progress bar which can print the progress.""" |
| 27 | |
| 28 | def __init__(self, task_num=0, bar_width=50, start=True, file=sys.stdout): |
| 29 | self.task_num = task_num |
| 30 | self.bar_width = bar_width |
| 31 | self.completed = 0 |
| 32 | self.file = file |
| 33 | if start: |
| 34 | self.start() |
| 35 | |
| 36 | @property |
| 37 | def terminal_width(self): |
| 38 | width, _ = get_terminal_size() |
| 39 | return width |
| 40 | |
| 41 | def start(self): |
| 42 | if self.task_num > 0: |
| 43 | self.file.write(f'[{" " * self.bar_width}] 0/{self.task_num}, ' |
| 44 | 'elapsed: 0s, ETA:') |
| 45 | else: |
| 46 | self.file.write('completed: 0, elapsed: 0s') |
| 47 | self.file.flush() |
| 48 | self.timer = Timer() |
| 49 | |
| 50 | def update(self, num_tasks=1): |
| 51 | assert num_tasks > 0 |
| 52 | self.completed += num_tasks |
| 53 | elapsed = self.timer.since_start() |
| 54 | if elapsed > 0: |
| 55 | fps = self.completed / elapsed |
| 56 | else: |
| 57 | fps = float('inf') |
| 58 | if self.task_num > 0: |
| 59 | percentage = self.completed / float(self.task_num) |
| 60 | eta = int(elapsed * (1 - percentage) / percentage + 0.5) |
| 61 | msg = f'\r[{{}}] {self.completed}/{self.task_num}, ' \ |
| 62 | f'{fps:.1f} task/s, elapsed: {int(elapsed + 0.5)}s, ' \ |
| 63 | f'ETA: {eta:5}s' |
| 64 | |
| 65 | bar_width = min(self.bar_width, |
| 66 | int(self.terminal_width - len(msg)) + 2, |
| 67 | int(self.terminal_width * 0.6)) |
| 68 | bar_width = max(2, bar_width) |
| 69 | mark_width = int(bar_width * percentage) |
| 70 | bar_chars = '>' * mark_width + ' ' * (bar_width - mark_width) |
| 71 | self.file.write(msg.format(bar_chars)) |
| 72 | else: |
| 73 | self.file.write( |
| 74 | f'completed: {self.completed}, elapsed: {int(elapsed + 0.5)}s,' |
| 75 | f' {fps:.1f} tasks/s') |
| 76 | self.file.flush() |
| 77 | |
| 78 | |
| 79 | def track_progress(func, tasks, bar_width=50, file=sys.stdout, **kwargs): |
no outgoing calls
no test coverage detected
searching dependent graphs…