Passed
Push — development/test ( 0a179d...9ec880 )
by Daniel
01:07
created

DataInputOutput.fn_save_data_frame_to_csv()   A

Complexity

Conditions 4

Size

Total Lines 13
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 13
rs 9.75
c 0
b 0
f 0
cc 4
nop 5
1
"""
2
Data Input Output class
3
"""
4
# package to add support for multi-language (i18n)
5
import gettext
6
# package to handle files/folders and related metadata/operations
7
import os
8
# package facilitating Data Frames manipulation
9
import pandas as pd
10
11
12
class DataInputOutput:
13
    lcl = None
14
15
    def __init__(self, default_language='en_US'):
16
        current_script = os.path.basename(__file__).replace('.py', '')
17
        lang_folder = os.path.join(os.path.dirname(__file__), current_script + '_Locale')
18
        self.lcl = gettext.translation(current_script, lang_folder, languages=[default_language])
19
20
    def fn_build_feedback_for_logger(self, operation_details):
21
        messages = {}
22
        if operation_details['operation'] == 'load':
23
            messages = {
24
                'failed': self.lcl.gettext(
25
                    'Error encountered on loading Pandas Data Frame '
26
                    + 'from {file_type} file type (see below)')
27
                    .replace('{file_type}', operation_details['format'].upper()),
28
                'success': self.lcl.gettext(
29
                    'All {files_counted} files of type {file_type} '
30
                    + 'successfully added to a Pandas Data Frame')
31
                    .replace('{files_counted}', str(operation_details['files counted']))
32
                    .replace('{file_type}', str(operation_details['format']))
33
            }
34
        elif operation_details['operation'] == 'save':
35
            messages = {
36
                'failed': self.lcl.gettext(
37
                    'Error encountered on saving Pandas Data Frame '
38
                    + 'into a {file_type} file type (see below)')
39
                    .replace('{file_type}', operation_details['format'].upper()),
40
                'success': self.lcl.gettext(
41
                    'Pandas Data Frame has just been saved to file "{file_name}", '
42
                    + 'considering {file_type} as file type')
43
                    .replace('{file_name}', operation_details['name'])
44
                    .replace('{file_type}', operation_details['format']),
45
            }
46
        return messages
47
48
    def fn_default_load_dict_message(self, in_file_list, in_format):
49
        return {
50
            'error details': None,
51
            'files counted': len(in_file_list),
52
            'format': in_format,
53
            'operation': 'load',
54
        }
55
56
    def fn_file_operation_logger(self, local_logger, in_logger_dict):
57
        messages = self.fn_build_feedback_for_logger(in_logger_dict)
58
        if in_logger_dict['error details'] is None:
59
            local_logger.info(messages['success'])
60
        else:
61
            local_logger.error(messages['failed'])
62
            local_logger.error(in_logger_dict['error details'])
63
64
    def fn_load_file_type_csv_into_data_frame(self, local_logger, in_file_list, csv_delimiter):
65
        details_for_logger = self.fn_default_load_dict_message(in_file_list, 'CSV')
66
        try:
67
            out_data_frame = pd.concat([pd.read_csv(filepath_or_buffer=current_file,
68
                                                    delimiter=csv_delimiter,
69
                                                    cache_dates=True,
70
                                                    index_col=None,
71
                                                    memory_map=True,
72
                                                    low_memory=False,
73
                                                    encoding='utf-8',
74
                                                    ) for current_file in in_file_list])
75
        except Exception as err:
76
            details_for_logger['error details'] = err
77
        self.fn_file_operation_logger(local_logger, details_for_logger)
78
        return out_data_frame
79
80
    def fn_load_file_type_excel_into_data_frame(self, local_logger, in_file_list):
81
        out_data_frame = None
82
        details_for_logger = self.fn_default_load_dict_message(in_file_list, 'Excel')
83
        try:
84
            out_data_frame = pd.concat([pd.read_excel(io=current_file,
85
                                                      verbose=True,
86
                                                      ) for current_file in in_file_list])
87
        except Exception as err:
88
            details_for_logger['error details'] = err
89
        self.fn_file_operation_logger(local_logger, details_for_logger)
90
        return out_data_frame
91
92
    def fn_load_file_type_pickle_into_data_frame(self, local_logger, in_file_list,
93
                                                 in_compression='infer'):
94
        out_data_frame = None
95
        details_for_logger = self.fn_default_load_dict_message(in_file_list, 'Pickle')
96
        try:
97
            out_data_frame = pd.concat([pd.read_pickle(filepath_or_buffer=current_file,
98
                                                       compression=in_compression,
99
                                                       ) for current_file in in_file_list])
100
        except Exception as err:
101
            details_for_logger['error details'] = err
102
        self.fn_file_operation_logger(local_logger, details_for_logger)
103
        return out_data_frame
104
105
    def fn_save_data_frame_to_csv(self, local_logger, in_data_frame, in_file_details, logger_dict):
106
        if in_file_details['format'].lower() == 'csv':
107
            if 'field-delimiter' not in in_file_details:
108
                in_file_details['field-delimiter'] = os.pathsep
109
            try:
110
                in_data_frame.to_csv(path_or_buf=in_file_details['name'],
111
                                     sep=in_file_details['field-delimiter'],
112
                                     header=True,
113
                                     index=False,
114
                                     encoding='utf-8')
115
            except Exception as err:
116
                logger_dict['error details'] = err
117
            self.fn_file_operation_logger(local_logger, logger_dict)
118
119
    def fn_save_data_frame_to_excel(self, local_logger, in_data_frame, in_file_details,
120
                                    logger_dict):
121
        if in_file_details['format'].lower() == 'excel':
122
            try:
123
                in_data_frame.to_excel(excel_writer=in_file_details['name'],
124
                                       engine='xlsxwriter',
125
                                       freeze_panes=(1, 1),
126
                                       verbose=True)
127
            except Exception as err:
128
                logger_dict['error details'] = err
129
            self.fn_file_operation_logger(local_logger, logger_dict)
130
131
    def fn_save_data_frame_to_pickle(self, local_logger, in_data_frame, in_file_details,
132
                                     logger_dict):
133
        if in_file_details['format'].lower() == 'pickle':
134
            if 'compression' not in in_file_details:
135
                in_file_details['compression'] = 'gzip'
136
            try:
137
                in_data_frame.to_pickle(path=in_file_details['name'],
138
                                        compression=in_file_details['compression'])
139
            except Exception as err:
140
                logger_dict['error details'] = err
141
            self.fn_file_operation_logger(local_logger, logger_dict)
142
143
    def fn_store_data_frame_to_file(self, local_logger, timmer, in_data_frame, in_file_details):
144
        timmer.start()
145
        self.fn_store_data_frame_to_file_validation(local_logger, in_file_details)
146
        if 'format' in in_file_details:
147
            details_for_logger = {
148
                'error details': None,
149
                'file name': in_file_details['name'],
150
                'format': in_file_details['format'],
151
                'operation': 'save',
152
            }
153
            self.fn_save_data_frame_to_csv(local_logger, in_data_frame,
154
                                           in_file_details, details_for_logger)
155
            self.fn_save_data_frame_to_excel(local_logger, in_data_frame,
156
                                             in_file_details, details_for_logger)
157
            self.fn_save_data_frame_to_pickle(local_logger, in_data_frame,
158
                                              in_file_details, details_for_logger)
159
        timmer.stop()
160
161
    def fn_store_data_frame_to_file_validation(self, local_logger, in_file_details):
162
        if 'format' in in_file_details:
163
            implemented_file_formats = ['csv', 'excel', 'pickle']
164
            given_format = in_file_details['format'].lower()
165
            if given_format not in implemented_file_formats:
166
                local_logger.error(self.lcl.gettext(
167
                    'File "format" attribute has a value of "{format_value}" '
168
                    + 'which is not among currently implemented values: '
169
                    + '"{implemented_file_formats}", therefore file saving is not possible')
170
                                   .replace('{format_value}', given_format)
171
                                   .replace('{implemented_file_formats}',
172
                                            '", "'.join(implemented_file_formats)))
173
        else:
174
            local_logger.error(self.lcl.gettext('File "format" attribute is mandatory '
175
                                                + 'in the file setting, but missing, '
176
                                                + 'therefore file saving is not possible'))
177