Passed
Push — master ( 9b1c49...b02625 )
by Guangyu
07:27 queued 13s
created

excelexporters.equipmentload   F

Complexity

Total Complexity 62

Size/Duplication

Total Lines 570
Duplicated Lines 7.19 %

Importance

Changes 0
Metric Value
wmc 62
eloc 409
dl 41
loc 570
rs 3.44
c 0
b 0
f 0

5 Functions

Rating   Name   Duplication   Size   Complexity  
A timestamps_data_all_equal_0() 0 6 3
A get_parameters_timestamps_lists_max_len() 0 7 3
B export() 41 41 5
A timestamps_data_not_equal_0() 0 6 3
F generate_excel() 0 480 48

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like excelexporters.equipmentload often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import base64
2
import uuid
3
import os
4
import re
5
from openpyxl.chart import LineChart, Reference
6
from openpyxl.chart.label import DataLabelList
7
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
8
from openpyxl.drawing.image import Image
9
from openpyxl import Workbook
10
import openpyxl.utils.cell as format_cell
11
import gettext
12
13
14
########################################################################################################################
15
# PROCEDURES
16
# Step 1: Validate the report data
17
# Step 2: Generate excel file
18
# Step 3: Encode the excel file to Base64
19
########################################################################################################################
20
21
22 View Code Duplication
def export(report,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
23
           name,
24
           reporting_start_datetime_local,
25
           reporting_end_datetime_local,
26
           period_type,
27
           language):
28
    ####################################################################################################################
29
    # Step 1: Validate the report data
30
    ####################################################################################################################
31
    if report is None:
32
        return None
33
34
    ####################################################################################################################
35
    # Step 2: Generate excel file from the report data
36
    ####################################################################################################################
37
    filename = generate_excel(report,
38
                              name,
39
                              reporting_start_datetime_local,
40
                              reporting_end_datetime_local,
41
                              period_type,
42
                              language)
43
    ####################################################################################################################
44
    # Step 3: Encode the excel file to Base64
45
    ####################################################################################################################
46
    binary_file_data = b''
47
    try:
48
        with open(filename, 'rb') as binary_file:
49
            binary_file_data = binary_file.read()
50
    except IOError as ex:
51
        pass
52
53
    # Base64 encode the bytes
54
    base64_encoded_data = base64.b64encode(binary_file_data)
55
    # get the Base64 encoded data using human-readable characters.
56
    base64_message = base64_encoded_data.decode('utf-8')
57
    # delete the file from server
58
    try:
59
        os.remove(filename)
60
    except NotImplementedError as ex:
61
        pass
62
    return base64_message
63
64
65
def generate_excel(report,
66
                   name,
67
                   reporting_start_datetime_local,
68
                   reporting_end_datetime_local,
69
                   period_type,
70
                   language):
71
    locale_path = './i18n/'
72
    if language == 'zh_CN':
73
        trans = gettext.translation('myems', locale_path, languages=['zh_CN'])
74
    elif language == 'de':
75
        trans = gettext.translation('myems', locale_path, languages=['de'])
76
    elif language == 'en':
77
        trans = gettext.translation('myems', locale_path, languages=['en'])
78
    else:
79
        trans = gettext.translation('myems', locale_path, languages=['en'])
80
    trans.install()
81
    _ = trans.gettext
82
    wb = Workbook()
83
    ws = wb.active
84
    ws.title = "EquipmentLoad"
85
86
    # Row height
87
    ws.row_dimensions[1].height = 102
88
89
    for i in range(2, 2000 + 1):
90
        ws.row_dimensions[i].height = 42
91
92
    # Col width
93
    ws.column_dimensions['A'].width = 1.5
94
    ws.column_dimensions['B'].width = 25.0
95
96
    for i in range(ord('C'), ord('L')):
97
        ws.column_dimensions[chr(i)].width = 15.0
98
99
    # Font
100
    name_font = Font(name='Arial', size=15, bold=True)
101
    title_font = Font(name='Arial', size=15, bold=True)
102
103
    table_fill = PatternFill(fill_type='solid', fgColor='1F497D')
104
    f_border = Border(left=Side(border_style='medium', color='00000000'),
105
                      right=Side(border_style='medium', color='00000000'),
106
                      bottom=Side(border_style='medium', color='00000000'),
107
                      top=Side(border_style='medium', color='00000000')
108
                      )
109
    b_border = Border(bottom=Side(border_style='medium', color='00000000'), )
110
111
    b_c_alignment = Alignment(vertical='bottom',
112
                              horizontal='center',
113
                              text_rotation=0,
114
                              wrap_text=True,
115
                              shrink_to_fit=False,
116
                              indent=0)
117
    c_c_alignment = Alignment(vertical='center',
118
                              horizontal='center',
119
                              text_rotation=0,
120
                              wrap_text=True,
121
                              shrink_to_fit=False,
122
                              indent=0)
123
    b_r_alignment = Alignment(vertical='bottom',
124
                              horizontal='right',
125
                              text_rotation=0,
126
                              wrap_text=True,
127
                              shrink_to_fit=False,
128
                              indent=0)
129
130
    # Img
131
    img = Image("excelexporters/myems.png")
132
    ws.add_image(img, 'A1')
133
134
    # Title
135
    ws['B3'].alignment = b_r_alignment
136
    ws['B3'] = _('Name') + ':'
137
    ws['C3'].border = b_border
138
    ws['C3'].alignment = b_c_alignment
139
    ws['C3'] = name
140
141
    ws['D3'].alignment = b_r_alignment
142
    ws['D3'] = _('Period Type') + ':'
143
    ws['E3'].border = b_border
144
    ws['E3'].alignment = b_c_alignment
145
    ws['E3'] = period_type
146
147
    ws['B4'].alignment = b_r_alignment
148
    ws['B4'] = _('Reporting Start Datetime') + ':'
149
    ws['C4'].border = b_border
150
    ws['C4'].alignment = b_c_alignment
151
    ws['C4'] = reporting_start_datetime_local
152
153
    ws['D4'].alignment = b_r_alignment
154
    ws['D4'] = _('Reporting End Datetime') + ':'
155
    ws['E4'].border = b_border
156
    ws['E4'].alignment = b_c_alignment
157
    ws['E4'] = reporting_end_datetime_local
158
159
    if "reporting_period" not in report.keys() or \
160
            "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
161
        filename = str(uuid.uuid4()) + '.xlsx'
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable str does not seem to be defined.
Loading history...
162
        wb.save(filename)
163
164
        return filename
165
    ####################################################################################################################
166
    # First: Statistics
167
    # 6: title
168
    # 7: table title
169
    # 8~2*ca_len table_data
170
    ####################################################################################################################
171
    reporting_period_data = report['reporting_period']
172
173
    if "names" not in reporting_period_data.keys() or \
174
            reporting_period_data['names'] is None or \
175
            len(reporting_period_data['names']) == 0:
176
        filename = str(uuid.uuid4()) + '.xlsx'
177
        wb.save(filename)
178
        return filename
179
180
    ws['B6'].font = title_font
181
    ws['B6'] = name + ' ' + _('Statistics')
182
183
    category = reporting_period_data['names']
184
185
    # table_title
186
    ws['B7'].fill = table_fill
187
    ws['B7'].font = title_font
188
    ws['B7'].alignment = c_c_alignment
189
    ws['B7'] = _('Reporting Period')
190
    ws['B7'].border = f_border
191
192
    ws['C7'].font = title_font
193
    ws['C7'].alignment = c_c_alignment
194
    ws['C7'] = _('Average Load')
195
    ws['C7'].border = f_border
196
197
    ws['D7'].font = title_font
198
    ws['D7'].alignment = c_c_alignment
199
    ws['D7'] = _('Maximum Load')
200
    ws['D7'].border = f_border
201
202
    ws['E7'].font = title_font
203
    ws['E7'].alignment = c_c_alignment
204
    ws['E7'] = _('Load Factor')
205
    ws['E7'].border = f_border
206
207
    # table_data
208
209
    for i, value in enumerate(category):
210
        row = i * 2 + 8
211
        ws['B' + str(row)].font = name_font
212
        ws['B' + str(row)].alignment = c_c_alignment
213
        ws['B' + str(row)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + "/H )"
214
        ws['B' + str(row)].border = f_border
215
216
        ws['B' + str(row + 1)].font = name_font
217
        ws['B' + str(row + 1)].alignment = c_c_alignment
218
        ws['B' + str(row + 1)] = _('Increment Rate')
219
        ws['B' + str(row + 1)].border = f_border
220
221
        ws['C' + str(row)].font = name_font
222
        ws['C' + str(row)].alignment = c_c_alignment
223
        ws['C' + str(row)] = round(reporting_period_data['averages'][i], 2) \
224
            if reporting_period_data['averages'][i] is not None else ''
225
        ws['C' + str(row)].border = f_border
226
        ws['C' + str(row)].number_format = '0.00'
227
228
        ws['C' + str(row + 1)].font = name_font
229
        ws['C' + str(row + 1)].alignment = c_c_alignment
230
        ws['C' + str(row + 1)] = str(round(reporting_period_data['averages_increment_rate'][i] * 100, 2)) + "%" \
231
            if reporting_period_data['averages_increment_rate'][i] is not None else '0.00%'
232
        ws['C' + str(row + 1)].border = f_border
233
234
        ws['D' + str(row)].font = name_font
235
        ws['D' + str(row)].alignment = c_c_alignment
236
        ws['D' + str(row)] = round(reporting_period_data['maximums'][i], 2) \
237
            if reporting_period_data['maximums'][i] is not None else ''
238
        ws['D' + str(row)].border = f_border
239
        ws['D' + str(row)].number_format = '0.00'
240
241
        ws['D' + str(row + 1)].font = name_font
242
        ws['D' + str(row + 1)].alignment = c_c_alignment
243
        ws['D' + str(row + 1)] = str(round(reporting_period_data['maximums_increment_rate'][i] * 100, 2)) + "%" \
244
            if reporting_period_data['maximums_increment_rate'][i] is not None else '0.00%'
245
        ws['D' + str(row + 1)].border = f_border
246
247
        ws['E' + str(row)].font = name_font
248
        ws['E' + str(row)].alignment = c_c_alignment
249
        ws['E' + str(row)] = round(reporting_period_data['factors'][i], 2) \
250
            if reporting_period_data['factors'][i] is not None else ''
251
        ws['E' + str(row)].border = f_border
252
        ws['E' + str(row)].number_format = '0.00'
253
254
        ws['E' + str(row + 1)].font = name_font
255
        ws['E' + str(row + 1)].alignment = c_c_alignment
256
        ws['E' + str(row + 1)] = str(round(reporting_period_data['factors_increment_rate'][i] * 100, 2)) + "%" \
257
            if reporting_period_data['factors_increment_rate'][i] is not None else '0.00%'
258
        ws['E' + str(row + 1)].border = f_border
259
260
    ####################################################################################################################
261
    # Third: Detailed Data
262
    # row_sat~ row_sat + 6*cal_len: line
263
    # row_da: table title
264
    # row_da + 1~: table_data
265
    ####################################################################################################################
266
    if "timestamps" not in reporting_period_data.keys() or \
267
            reporting_period_data['timestamps'] is None or \
268
            len(reporting_period_data['timestamps']) == 0:
269
        pass
270
    else:
271
        timestamps = reporting_period_data['timestamps'][0]
272
        names = reporting_period_data['names']
273
        ca_len = len(names)
274
        real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
275
        time_len = len(timestamps)
276
        # row_lines == the number of rows of lines
277
        row_lines = 6 * ca_len
278
        # row_sat == the number of rows of statistical analysis table
279
        row_sat = 9 + 2 * ca_len
280
        # row_da == the number of rows of Detailed data
281
        row_da = row_sat + row_lines + real_timestamps_len * 7 + 2
282
283
        ws['B' + str(row_da)].font = title_font
284
        ws['B' + str(row_da)] = name + ' ' + _('Detailed Data')
285
        # table_title
286
        ws['B' + str(row_da + 1)].fill = table_fill
287
        ws['B' + str(row_da + 1)].font = name_font
288
        ws['B' + str(row_da + 1)].alignment = c_c_alignment
289
        ws['B' + str(row_da + 1)] = _("Datetime")
290
        ws['B' + str(row_da + 1)].border = f_border
291
292
        for i in range(0, ca_len):
293
            col_average = chr(ord('C') + 2 * i)
294
            col_maximum = chr(ord('D') + 2 * i)
295
296
            ws[col_average + str(row_da + 1)].font = name_font
297
            ws[col_average + str(row_da + 1)].alignment = c_c_alignment
298
            ws[col_average + str(row_da + 1)] = names[i] + " " + _("Average Load") + "(" + reporting_period_data['units'][
299
                i] + "/H)"
300
            ws[col_average + str(row_da + 1)].border = f_border
301
302
            ws[col_maximum + str(row_da + 1)].font = name_font
303
            ws[col_maximum + str(row_da + 1)].alignment = c_c_alignment
304
            ws[col_maximum + str(row_da + 1)] = names[i] + " " + _("Maximum Load") + "(" + reporting_period_data['units'][
305
                i] + "/H)"
306
            ws[col_maximum + str(row_da + 1)].border = f_border
307
        # table_date
308
        for i in range(0, time_len):
309
            rows = i + row_da + 2
310
311
            ws['B' + str(rows)].font = name_font
312
            ws['B' + str(rows)].alignment = c_c_alignment
313
            ws['B' + str(rows)] = timestamps[i]
314
            ws['B' + str(rows)].border = f_border
315
316
            for index in range(0, ca_len):
317
                col_average = chr(ord('C') + 2 * index)
318
                col_maximum = chr(ord('D') + 2 * index)
319
320
                ws[col_average + str(rows)].font = name_font
321
                ws[col_average + str(rows)].alignment = c_c_alignment
322
                ws[col_average + str(rows)] = reporting_period_data['sub_averages'][index][i] \
323
                    if reporting_period_data['sub_maximums'][index] is not None else ''
324
                ws[col_average + str(rows)].number_format = '0.00'
325
                ws[col_average + str(rows)].border = f_border
326
327
                ws[col_maximum + str(rows)].font = name_font
328
                ws[col_maximum + str(rows)].alignment = c_c_alignment
329
                ws[col_maximum + str(rows)] = reporting_period_data['sub_maximums'][index][i] \
330
                    if reporting_period_data['sub_maximums'][index] is not None else ''
331
                ws[col_maximum + str(rows)].number_format = '0.00'
332
                ws[col_maximum + str(rows)].border = f_border
333
        current_row_number = row_da + 1 + time_len
334
335
        # LineChart
336
        for i in range(0, ca_len):
337
            lc = LineChart()
338
            lc.title = _("Reporting Period Maximum Load")
339
            lc.style = 10
340
            lc.x_axis.majorTickMark = 'in'
341
            lc.y_axis.majorTickMark = 'in'
342
            lc.smooth = True
343
            lc.x_axis.crosses = 'min'
344
            lc.height = 8.25
345
            lc.width = 24
346
            lc.dLbls = DataLabelList()
347
            lc.dLbls.dLblPos = 't'
348
            lc.dLbls.showVal = True
349
            times = Reference(ws, min_col=2, min_row=row_da + 2,
350
                              max_row=row_da + 2 + time_len)
351
            lc_data = Reference(ws, min_col=2 + 2 * (i+1), min_row=row_da + 1,
352
                                max_row=row_da + 1 + time_len)
353
            lc.add_data(lc_data, titles_from_data=True)
354
            lc.set_categories(times)
355
            ser = lc.series[0]
356
            ser.marker.symbol = "diamond"
357
            ser.marker.size = 5
358
            chart_col = 'B'
359
            chart_cell = str(row_sat + 6 * i)
360
            ws.add_chart(lc, chart_col + chart_cell)
361
362
    ####################################################################################################################
363
    current_sheet_parameters_row_number = row_sat + 1 + 6 * ca_len
0 ignored issues
show
introduced by
The variable ca_len does not seem to be defined for all execution paths.
Loading history...
introduced by
The variable row_sat does not seem to be defined for all execution paths.
Loading history...
364
    if 'parameters' not in report.keys() or \
365
            report['parameters'] is None or \
366
            'names' not in report['parameters'].keys() or \
367
            report['parameters']['names'] is None or \
368
            len(report['parameters']['names']) == 0 or \
369
            'timestamps' not in report['parameters'].keys() or \
370
            report['parameters']['timestamps'] is None or \
371
            len(report['parameters']['timestamps']) == 0 or \
372
            'values' not in report['parameters'].keys() or \
373
            report['parameters']['values'] is None or \
374
            len(report['parameters']['values']) == 0 or \
375
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
376
        pass
377
    else:
378
379
        ################################################################################################################
380
        # new worksheet
381
        ################################################################################################################
382
383
        parameters_data = report['parameters']
384
        parameters_names_len = len(parameters_data['names'])
385
386
        file_name = (re.sub(r'[^A-Z]', '', ws.title))+'_'
387
        parameters_ws = wb.create_sheet(file_name + 'Parameters')
388
389
        parameters_timestamps_data_max_len = \
390
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
391
392
        # Row height
393
        parameters_ws.row_dimensions[1].height = 102
394
        for i in range(2, 7 + 1):
395
            parameters_ws.row_dimensions[i].height = 42
396
397
        for i in range(8, parameters_timestamps_data_max_len + 10):
398
            parameters_ws.row_dimensions[i].height = 60
399
400
        # Col width
401
        parameters_ws.column_dimensions['A'].width = 1.5
402
403
        parameters_ws.column_dimensions['B'].width = 25.0
404
405
        for i in range(3, 12 + parameters_names_len * 3):
406
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
407
408
        # Img
409
        img = Image("excelexporters/myems.png")
410
        parameters_ws.add_image(img, 'A1')
411
412
        # Title
413
414
        parameters_ws['B3'].alignment = b_r_alignment
415
        parameters_ws['B3'] = _('Name') + ':'
416
        parameters_ws['C3'].border = b_border
417
        parameters_ws['C3'].alignment = b_c_alignment
418
        parameters_ws['C3'] = name
419
420
        parameters_ws['D3'].alignment = b_r_alignment
421
        parameters_ws['D3'] = _('Period Type') + ':'
422
        parameters_ws['E3'].border = b_border
423
        parameters_ws['E3'].alignment = b_c_alignment
424
        parameters_ws['E3'] = period_type
425
426
        parameters_ws['B4'].alignment = b_r_alignment
427
        parameters_ws['B4'] = _('Reporting Start Datetime') + ':'
428
        parameters_ws['C4'].border = b_border
429
        parameters_ws['C4'].alignment = b_c_alignment
430
        parameters_ws['C4'] = reporting_start_datetime_local
431
432
        parameters_ws['D4'].alignment = b_r_alignment
433
        parameters_ws['D4'] = _('Reporting End Datetime') + ':'
434
        parameters_ws['E4'].border = b_border
435
        parameters_ws['E4'].alignment = b_c_alignment
436
        parameters_ws['E4'] = reporting_end_datetime_local
437
438
        parameters_ws_current_row_number = 6
439
440
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
441
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters')
442
443
        parameters_ws_current_row_number += 1
444
445
        parameters_table_start_row_number = parameters_ws_current_row_number
446
447
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
448
449
        parameters_ws_current_row_number += 1
450
451
        table_current_col_number = 2
452
453
        for i in range(0, parameters_names_len):
454
455
            if len(parameters_data['timestamps'][i]) == 0:
456
                continue
457
458
            col = format_cell.get_column_letter(table_current_col_number)
459
460
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
461
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
462
463
            col = format_cell.get_column_letter(table_current_col_number + 1)
464
465
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
466
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
467
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
468
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
469
            parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
470
471
            table_current_row_number = parameters_ws_current_row_number
472
473
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
474
                col = format_cell.get_column_letter(table_current_col_number)
475
476
                parameters_ws[col + str(table_current_row_number)].border = f_border
477
                parameters_ws[col + str(table_current_row_number)].font = title_font
478
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
479
                parameters_ws[col + str(table_current_row_number)] = value
480
481
                col = format_cell.get_column_letter(table_current_col_number + 1)
482
483
                parameters_ws[col + str(table_current_row_number)].border = f_border
484
                parameters_ws[col + str(table_current_row_number)].font = title_font
485
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
486
                parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
487
488
                table_current_row_number += 1
489
490
            table_current_col_number = table_current_col_number + 3
491
492
        ################################################################################################################
493
        # parameters chart and parameters table
494
        ################################################################################################################
495
496
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
497
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters')
498
499
        current_sheet_parameters_row_number += 1
500
501
        chart_start_row_number = current_sheet_parameters_row_number
502
503
        col_index = 0
504
505
        for i in range(0, parameters_names_len):
506
507
            if len(parameters_data['timestamps'][i]) == 0:
508
                continue
509
510
            line = LineChart()
511
            data_col = 3 + col_index * 3
512
            labels_col = 2 + col_index * 3
513
            col_index += 1
514
            line.title = _('Parameters') + ' - ' + \
515
                         parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
516
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
517
                               max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
518
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
519
                                  max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
520
            line.add_data(line_data, titles_from_data=True)
521
            line.set_categories(labels)
522
            line_data = line.series[0]
523
            line_data.marker.symbol = "circle"
524
            line_data.smooth = True
525
            line.x_axis.crosses = 'min'
526
            line.height = 8.25
527
            line.width = 24
528
            line.dLbls = DataLabelList()
529
            line.dLbls.dLblPos = 't'
530
            line.dLbls.showVal = False
531
            line.dLbls.showPercent = False
532
            chart_col = 'B'
533
            chart_cell = chart_col + str(chart_start_row_number)
534
            chart_start_row_number += 6
535
            ws.add_chart(line, chart_cell)
536
537
        current_sheet_parameters_row_number = chart_start_row_number
538
539
        current_sheet_parameters_row_number += 1
540
    ####################################################################################################################
541
    filename = str(uuid.uuid4()) + '.xlsx'
542
    wb.save(filename)
543
544
    return filename
545
546
547
def timestamps_data_all_equal_0(lists):
548
    for i, value in enumerate(list(lists)):
549
        if len(value) > 0:
550
            return False
551
552
    return True
553
554
555
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
556
    max_len = 0
557
    for i, value in enumerate(list(parameters_timestamps_lists)):
558
        if len(value) > max_len:
559
            max_len = len(value)
560
561
    return max_len
562
563
564
def timestamps_data_not_equal_0(lists):
565
    number = 0
566
    for i, value in enumerate(list(lists)):
567
        if len(value) > 0:
568
            number += 1
569
    return number
570