-
Notifications
You must be signed in to change notification settings - Fork 160
/
progress_bar.py
128 lines (107 loc) · 3.89 KB
/
progress_bar.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import math
import time
class PorgressBar(object):
def __init__(self, name='', total=100, bar_width = 22, autorender=True):
self.total = total
self.progress = 0
self.name = name
self.bar_width = bar_width
self.autorender = autorender
self.parent_bath_job = None
def on_progress_done(self, progress):
self.progress += progress
if self.progress > self.total:
self.progress = self.total
if self.autorender:
self.print()
if self.parent_bath_job:
self.parent_bath_job.on_progress_done(progress)
def render(self):
if self.total == 0:
return
fraction = self.progress / self.total
done = math.floor( fraction * (self.bar_width-2))
percent = math.floor(fraction * 100)
return '[{}{}] {}{}%'.format( done * '#',
(self.bar_width - 2 - done ) * ' ',
(3 - len(str(percent)) ) * ' ',
percent)
def print( self ):
# start from newline begin
print('\r',end='')
# clear last line
print('' * (len(self.name) + 4 + self.bar_width), end='')
print('\r',end='')
# if progressbarr have a name, print it
if self.name != '':
print(self.name, ':', self.render(),end='')
else:
print(self.render)
class PorgressBarBath(object):
def __init__(self, name, bar_width = 40):
self.jobs = []
self.name = name
self.progress = PorgressBar(name, 0, bar_width=bar_width, autorender=False )
self.last_render_lines = 0
self.bar_width = bar_width
def get_subjob(self, name):
return next( (x for x in self.jobs if x.name == name), None)
def add_subjob(self, job):
if isinstance(job, PorgressBar):
job.parent_bath_job = self
job.autorender = False
job.bar_width = self.bar_width
self.jobs.append(job)
self.progress.total += job.total
def on_progress_done(self, progress):
self.progress.on_progress_done(progress)
self.print()
def print( self ):
max_line_width = 0
for job in self.jobs:
line_width = (len(job.name) + 6 + job.bar_width)
max_line_width = max( max_line_width, line_width)
# start from newline begin
print('\r',end='')
# return to print origin
if self.last_render_lines > 0:
print( '\r\u001b[{n}A\r'.format(n = self.last_render_lines), end='')
# print overall progress
print(self.name, ':', self.progress.render())
self.last_render_lines = 1
# print subjobs
for job in self.jobs:
job_bar = job.render()
# clear line
line_width = (len(job.name) + 4 + job.bar_width)
print('' * line_width, end='')
print('\r',end='')
print( job_bar, ':', ' ' * (max_line_width - line_width), job.name)
self.last_render_lines += 1
if __name__ == '__main__':
pb = PorgressBar('reading stuff', 200, 60, True)
pb_1 = PorgressBar('writing', 100, 22, True)
pb_2 = PorgressBar('sleeping', 20, 22, True)
pb_3 = PorgressBar('reading again', 200, 60, True)
bath = PorgressBarBath('Overall')
bath.add_subjob(pb)
bath.add_subjob(pb_1)
bath.add_subjob(pb_2)
bath.add_subjob(pb_3)
for i in range(0, 200):
pb.on_progress_done(1)
time.sleep(0.01)
time.sleep(1)
for i in range(0, 100):
pb_1.on_progress_done(1)
time.sleep(0.01)
time.sleep(1)
pb_2.on_progress_done(3)
time.sleep(0.3)
pb_2.on_progress_done(7)
time.sleep(0.3)
pb_2.on_progress_done(10)
for i in range(0, 200):
pb_3.on_progress_done(1)
time.sleep(0.01)
print('\n')