凯鲁嘎吉
用书写铭记日常,最迷人的不在远方

Python小练习:进度条

作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/

用Python两种方式实现进度条功能,一种是自定义的进度条,一种是调用tqdm库来实现。

1. process_test.py

  1 # -*- coding: utf-8 -*-
  2 # Author:凯鲁嘎吉 Coral Gajic
  3 # https://www.cnblogs.com/kailugaji/
  4 # Python小练习:进度条
  5 import time
  6 import math
  7 from tqdm import tqdm
  8 
  9 # 字符串左对齐右对齐
 10 def format_for_process(params):
 11     new_params = []
 12     for k, v in params.items():
 13         k = k.rjust(18)  # 右对齐
 14         # rjust() 方法是向字符串的左侧填充指定字符,从而达到右对齐文本的目的。
 15         v = '{:<12}'.format(round(v, 6))[:12]  # 左对齐,并且保留6位小数
 16         new_params.append([k, v])
 17     return new_params
 18 
 19 class Progress:
 20 # 用于在控制台中显示进度条
 21     def __init__(self, total, name='Progress', ncol=3, max_length=30, indent=0, line_width=100, speed_update_freq=50):
 22         self.total = total # 进度总量
 23         self.name = name # 进度条的名称
 24         self.ncol = ncol  # 3 # 进度条的列数
 25         self.max_length = max_length  # 30 进度条的最大长度
 26         self.indent = indent  # 0 进度条的缩进量
 27         self.line_width = line_width  # 100 进度条的宽度
 28         self._speed_update_freq = speed_update_freq  # 50 进度条的速度更新频率
 29         self._step = 0 # 进度条的当前步数
 30         self._prev_line = '\033[F' # 上一次进度条的内容
 31         self._clear_line = ' ' * self.line_width  # 100, ''中间空100个字符 清空进度条的内容
 32         # '                         '
 33         self._pbar_size = self.ncol * self.max_length  # 3*30 进度条的分组大小
 34         self._complete_pbar = '#' * self._pbar_size  # # * 90,90个# 完成进度条的内容
 35         # #######################################
 36         self._incomplete_pbar = ' ' * self._pbar_size # 未完成进度条的内容
 37         # '                                  '
 38         self.lines = [''] # 进度条的内容列表
 39         self.fraction = '{} / {}'.format(0, self.total) # 进度条的进度
 40         self.resume() # 重新开始进度条的计时
 41 
 42     def update(self, n=1):
 43         self._step += n
 44         if self._step % self._speed_update_freq == 0:
 45             self._time0 = time.time()
 46             self._step0 = self._step
 47     # 该方法的作用是更新步数_step并在每次更新后打印当前时间_time0和步数_step0。
 48     # 如果_step的值是_speed_update_freq的倍数,则打印一个换行符,并将_time0和_step0设置为当前时间和步数。
 49     # 如果_step的值不是_speed_update_freq的倍数,则不打印任何内容,并将_time0和_step0设置为当前时间和步数。
 50     # 如果_step的值是0,则打印一个换行符,并将_time0和_step0设置为当前时间和步数。
 51 
 52     def resume(self):
 53         self._skip_lines = 1
 54         print('\n', end='')
 55         self._time0 = time.time()
 56         self._step0 = self._step
 57     # self._skip_lines是一个实例变量,其值为1表示正在执行代码块,为0表示已经执行完毕。
 58     # 该方法的作用是在每次更新后打印一个换行符,并将_time0和_step0设置为当前时间和步数。
 59     # 如果self._skip_lines的值是1,则在每行代码末尾打印一个换行符。
 60 
 61     def pause(self):
 62         self._clear()
 63         self._skip_lines = 1
 64 
 65     def set_description(self, params=[]):
 66         # Position
 67         self._clear()
 68         # Percent
 69         percent, fraction = self._format_percent(self._step, self.total)
 70         self.fraction = fraction
 71         # Speed
 72         speed = self._format_speed(self._step)
 73         # Params
 74         num_params = len(params)
 75         nrow = math.ceil(num_params / self.ncol)  # 返回大于等于参数x的最小整数,即对浮点数向上取整
 76         params_split = self._chunk(params, self.ncol)
 77         params_string, lines = self._format(params_split)
 78         self.lines = lines
 79 
 80         description = '{} | {}{}'.format(percent, speed, params_string)
 81         print(description)
 82         self._skip_lines = nrow + 1
 83 
 84     def set_description2(self, params=[]):
 85         # Params
 86         num_params = len(params)
 87         nrow = math.ceil(num_params / self.ncol)  # 返回大于等于参数x的最小整数,即对浮点数向上取整
 88         params_split = self._chunk(params, self.ncol)
 89         params_string, lines = self._format(params_split)
 90         print('\n', params_string)
 91 
 92     def _clear(self):
 93         position = self._prev_line * self._skip_lines
 94         empty = '\n'.join([self._clear_line for _ in range(self._skip_lines)])
 95         print(position, end='')
 96         print(empty)
 97         print(position, end='')
 98 
 99     def _format_percent(self, n, total):
100         if total:
101             percent = n / float(total)
102 
103             complete_entries = int(percent * self._pbar_size)
104             incomplete_entries = self._pbar_size - complete_entries
105 
106             pbar = self._complete_pbar[:complete_entries] + self._incomplete_pbar[:incomplete_entries]
107             fraction = '{} / {}'.format(n, total)
108             string = '{} [{}] {:3d}%'.format(fraction, pbar, int(percent * 100))
109         else:
110             fraction = '{}'.format(n)
111             string = '{} iterations'.format(n)
112         return string, fraction
113         # string:
114         # 9 / 10 [#################################################################################         ]  90%
115         # fraction: 9 / 10
116 
117     # 输出x.x Hz
118     def _format_speed(self, n):
119         num_steps = n - self._step0
120         t = time.time() - self._time0
121         speed = num_steps / (t + float("1e-8"))
122         string = '{:.1E} Hz'.format(speed)
123         if num_steps > 0:
124             self._speed = string
125         return string
126 
127     def _chunk(self, l, n):
128         return [l[i:i + n] for i in range(0, len(l), n)]
129 
130     def _format(self, chunks):
131         lines = [self._format_chunk(chunk) for chunk in chunks]
132         lines.insert(0, '')
133         padding = '\n' + ' ' * self.indent
134         string = padding.join(lines)
135         return string, lines
136 
137     def _format_chunk(self, chunk):
138         line = ' | '.join([self._format_param(param) for param in chunk])
139         return line
140 
141     def _format_param(self, param):
142         k, v = param
143         return '{} : {}'.format(k, v)[:self.max_length]
144 
145     def stamp(self):
146         if self.lines != ['']:
147             params = ' | '.join(self.lines)
148             string = '[ {} ] {}{} | {}'.format(self.name, self.fraction, params, self._speed)
149             # name: Process
150             # fraction: 6 / 6
151             # 输出:
152             # [ Progress ] 6 / 6 |             weight : 149.8228  |             height : 214.32345 |             repeat : 45.8241   |              alpha : 43.32475  |               beta : 50.8254   |              gamma : 60.32605  | 6.0E+03 Hz
153             self._clear()
154             print(string)
155             self._skip_lines = 1
156         else:
157             self._clear()
158             self._skip_lines = 0
159 
160     def close(self):
161         self.pause()
162 
163 total_num = 6
164 # 自己实现的进度条功能
165 progress = Progress(total_num)
166 for i in range(total_num):
167     progress.update()
168     params = {"weight": 127.0 - (i+1.5)*3.5112,
169               "height": 185.0 - (i+1.5)*4.5113,
170               "repeat": 10.0 - (i+1.5)*5.5114,
171               "alpha": 1.0 + (i+1.5)*6.5115,
172               "beta": 2.0 + (i+1.5)*7.5116,
173               "gamma": 5.0 + (i+1.5)*8.5117}
174     progress.set_description(format_for_process(params))
175 progress.stamp()
176 progress.close()
177 print('-------------------------------------------------------------------------')
178 # Python自带的进度条包
179 for i in tqdm(range(total_num)):
180      time.sleep(0.1)
181      params = {"weight": 127.0 - (i + 1.5) * 3.5112,
182                "height": 185.0 - (i + 1.5) * 4.5113,
183                "repeat": 10.0 - (i + 1.5) * 5.5114,
184                "alpha": 1.0 + (i + 1.5) * 6.5115,
185                "beta": 2.0 + (i + 1.5) * 7.5116,
186                "gamma": 5.0 + (i + 1.5) * 8.5117}
187      progress.set_description2(format_for_process(params))
188 progress.stamp()
189 progress.close()

2. 结果

D:\ProgramData\Anaconda3\python.exe "D:/Python code/2023.3 exercise/time/process_test.py"

                                                                                                    
1 / 6 [###############                                                                           ]  16% | 1.0E+08 Hz
            weight : 121.7332  |             height : 178.23305 |             repeat : 1.7329   
             alpha : 10.76725  |               beta : 13.2674   |              gamma : 17.76755 
                                                                                                    
                                                                                                    
                                                                                                    
2 / 6 [##############################                                                            ]  33% | 2.0E+08 Hz
            weight : 118.222   |             height : 173.72175 |             repeat : -3.7785  
             alpha : 17.27875  |               beta : 20.779    |              gamma : 26.27925 
                                                                                                    
                                                                                                    
                                                                                                    
3 / 6 [#############################################                                             ]  50% | 3.0E+08 Hz
            weight : 114.7108  |             height : 169.21045 |             repeat : -9.2899  
             alpha : 23.79025  |               beta : 28.2906   |              gamma : 34.79095 
                                                                                                    
                                                                                                    
                                                                                                    
4 / 6 [############################################################                              ]  66% | 4.0E+08 Hz
            weight : 111.1996  |             height : 164.69915 |             repeat : -14.8013 
             alpha : 30.30175  |               beta : 35.8022   |              gamma : 43.30265 
                                                                                                    
                                                                                                    
                                                                                                    
5 / 6 [###########################################################################               ]  83% | 5.0E+03 Hz
            weight : 107.6884  |             height : 160.18785 |             repeat : -20.3127 
             alpha : 36.81325  |               beta : 43.3138   |              gamma : 51.81435 
                                                                                                    
                                                                                                    
                                                                                                    
6 / 6 [##########################################################################################] 100% | 6.0E+03 Hz
            weight : 104.1772  |             height : 155.67655 |             repeat : -25.8241 
             alpha : 43.32475  |               beta : 50.8254   |              gamma : 60.32605 
                                                                                                    
                                                                                                    
                                                                                                    
[ Progress ] 6 / 6 |             weight : 104.1772  |             height : 155.67655 |             repeat : -25.8241  |              alpha : 43.32475  |               beta : 50.8254   |              gamma : 60.32605  | 6.0E+03 Hz
                                                                                                    
-------------------------------------------------------------------------
  0%|          | 0/6 [00:00<?, ?it/s]
 17%|█▋        | 1/6 [00:00<00:00,  9.95it/s] 
            weight : 121.7332  |             height : 178.23305 |             repeat : 1.7329   
             alpha : 10.76725  |               beta : 13.2674   |              gamma : 17.76755 

 33%|███▎      | 2/6 [00:00<00:00,  9.63it/s] 
            weight : 118.222   |             height : 173.72175 |             repeat : -3.7785  
             alpha : 17.27875  |               beta : 20.779    |              gamma : 26.27925 

 
            weight : 114.7108  |             height : 169.21045 |             repeat : -9.2899  
             alpha : 23.79025  |               beta : 28.2906   |              gamma : 34.79095 
 50%|█████     | 3/6 [00:00<00:00,  9.46it/s]
 67%|██████▋   | 4/6 [00:00<00:00,  9.33it/s] 
            weight : 111.1996  |             height : 164.69915 |             repeat : -14.8013 
             alpha : 30.30175  |               beta : 35.8022   |              gamma : 43.30265 

 83%|████████▎ | 5/6 [00:00<00:00,  9.28it/s] 
            weight : 107.6884  |             height : 160.18785 |             repeat : -20.3127 
             alpha : 36.81325  |               beta : 43.3138   |              gamma : 51.81435 

100%|██████████| 6/6 [00:00<00:00,  9.34it/s]
 
            weight : 104.1772  |             height : 155.67655 |             repeat : -25.8241 
             alpha : 43.32475  |               beta : 50.8254   |              gamma : 60.32605 
                                                                                                    
[ Progress ] 6 / 6 |             weight : 104.1772  |             height : 155.67655 |             repeat : -25.8241  |              alpha : 43.32475  |               beta : 50.8254   |              gamma : 60.32605  | 6.0E+03 Hz
                                                                                                    

Process finished with exit code 0

完成。

posted on 2023-04-06 15:06  凯鲁嘎吉  阅读(74)  评论(0编辑  收藏  举报