-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathremodeling_module.py
257 lines (179 loc) · 9.17 KB
/
remodeling_module.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# -*- coding: utf-8 -*-
'''
Módulo de acondicionamiento de las colecciones utilizadas
Es el encargado de analizar la información introducida por el usuario respecto a colecciones y evaluaciones para luego procesarla y acomodarla a un
formato que los demás componentes del sistema puedan utilizar.
Además, es el encargado de filtrar los documentos no válidos.
Los documentos no válidos son aquellos que son muy cortos (de forma predeterminada, aquellos documentos con menos de 50 términos) o que no están en español.
'''
from utilities import configuration
class Remodeling_Module():
def __init__(self,
text_analyzer=''
):
self._text_analyzer=text_analyzer
'''
MÉTODOS PRINCIPALES
'''
'''
Filtra y acondiciona la entrada introducida por el usuario.
Lee los csvs introducidos y genera estructuras adecuadas para que los demás componentes del sistema utilicen la información introducida
por el usuario.
Además, informa (a través de mensajes por pantalla) cuando algún documento de la colección no es válido.
Input:
-csv_file_content: String. Ubicación del fichero csv que incluye el contenido de los documentos a utilizar.
-csv_file_evaluation: String. Ubicación del fichero csv que incluye las evaluaciones asociadas a los documentos a utilizar.
-separator: String. Símbolo que sirve de separador dentro de los ficheros csv.
Output:
-files_evals: Dict. Diccionario cuyas claves son los nombres de los ficheros y los valores las evaluaciones asociadas a cada criterio.
-files_cont: Dict. Diccionario cuyas claves son los nombres de los ficheros y los valores son el contenido del propio documento.
'''
#devuelve dos diccionarios. Ambos tienen como clave los nombres de los docs.
#Como valores, uno tiene las evaluaciones y otro es el contenido del documento.
def prepare_and_filter_docs(self,
csv_file_content='',
csv_file_evaluations='',
separator=';'
):
#dict. claves: nombres de los docs. valores: evaluaciones (lista de OK/KO) por criterio.
files_evaluations= self._read_csv_files_evaluations(csv_file=csv_file_evaluations,
separator=separator)
#dict. claves: nombres de los docs. valores: contenido del texto.
files_contents= self.read_text_content_from_csv(csv_file=csv_file_content, separator=separator)
#Mezclamos el contenido de ambos. Atendemos principalmente a los docs de las evaluaciones.
files=dict()
for x in files_evaluations.keys():
files[x]=files_contents[x]
#filtramos los documentos.
correct=self._filter_unvalid_files(files=files)
files_evals=dict()
files_cont=dict()
for x in correct:
files_evals[x]=files_evaluations[x].copy()
files_cont[x]=files_contents[x]
return files_evals, files_cont
'''
Dado un texto, evalúa si es válido.
Un documento es válido si su tamaño es mayor que 50 términos (parámetro configurable) y
si está en español.
Input:
-text: String. Texto a evaluar.
Output:
-Boolean. True si es válido. False si no.
'''
def check_text_validity(self,text):
size=0
words=''
paragraphs=text.split('\n')
for x in paragraphs:
for y in x.split():
size+=1
words+=y+' '
if size == configuration['min_text_size'] and self._check_language(words.lower()):
return True
return False
'''
Obtiene los resultados obtenidos si hubiesemos aplicado una colección filtrada de criterios.
Este método se utiliza exclusivamente en la funcionalidad de autoconfiguración del sistema.
Input:
-results: Dict. resultados obtenidos en la ejecución (y resultados que queremos filtrar).
-new_criteria: Dict. nueva colección de criterios utilizada
Output:
-List: resultados filtrados en base a los nuevos criterios.
'''
def filter_using_criteria(self, results, new_criteria):
num_crit=len(results[0]) #Obtenemos el número de criterios a tratar.
num_docs=len(results)
criteria_keys=list(new_criteria.keys())
filtered_results=list()
for doc in range(num_docs):
new_doc=list()
for crit in range(num_crit):
subcr_found=results[doc][crit][2]
found=0
for x in subcr_found:
if x in new_criteria[criteria_keys[crit]]:
found+=1
new_doc.append(('OK',found/len(new_criteria[criteria_keys[crit]])))
filtered_results.append(new_doc)
return filtered_results
#Devuelve dos listas con los NOMBRES de los docs correctos y los incorrectos.
def filter_files(self,
files=dict()
):
correct=list()
incorrect=list()
for filename, filecontent in files.items():
if self.check_text_validity(filecontent):
correct.append(filename)
else:
incorrect.append(filename)
return correct, incorrect
#Lee el contenido de los textos a partir del csv correspondiente.
#Presupone que el contenido del csv incluye una cabecera.
def read_text_content_from_csv(self,csv_file='', separator=''):
with open(csv_file, 'r', encoding='latin-1') as f:
csv_content=f.read()
result=dict() #Diccionario cuyas claves serán el nombre del fichero y el valor será el contenido del mismo.
files= csv_content.split('\n')
files.pop(0) #Eliminamos la cabecera
for file in files:
fields= file.split(separator)
if len(fields) > 1: #Si no es una línea vacía (la última).
result[fields[2]]=fields[3]
return result
'''
MÉTODOS SECUNDARIOS
'''
#Lee el csv de las evaluaciones asociadas a los documentos.
def _read_csv_files_evaluations(self,
csv_file='',
header=True,
encoding='latin-1',
separator='#',
source_dir=''
):
with open(csv_file, 'r', encoding='latin-1') as f:
content=f.read()
#Variable en la que se volcarán los resultados
files=dict()
lines=content.split('\n')
#Eliminamos la última línea porque está vacía.
lines.pop()
if not header:
#Obtenemos el número de criterios.
num_crit= len(lines[0].split(separator))
#Insertamos el valor de la primera línea (posición 0)
line_content=lines[0].split(separator)
results=list()
for x in range(1,num_crit):
results.append(line_content[x])
filepath= line_content[0] if source_dir == '' else source_dir+'/'+line_content[0]
files[filepath]=results
else:
#Obtenemos el número de criterios.
num_crit= len(lines[1].split(separator))
#Insertamos los elementos del csv en el resultado.
for x in range(1, len(lines)):
line_content=lines[x].split(separator)
results=list()
for x in range(1,num_crit):
results.append(line_content[x])
filepath= line_content[0] if source_dir == '' else source_dir+'/'+line_content[0]
files[filepath]=results
return files
#Devuelve si el lenguaje del texto es el adecuado (español).
def _check_language(self,text):
res=self._text_analyzer.detect_language(text)
return res =='es'
#files: diccionario cuyas claves son los nombres de los ficheros y los valores su contenido.
#Devuelve una lista con los nombres de los documentos correctos. Contiene los NOMBRES de los CORRECTOS.
def _filter_unvalid_files(self,
files=dict()
):
correct, incorrect =self.filter_files(files=files)
if len(incorrect)!=0:
print('Los siguientes documentos no son válidos:')
for x in incorrect:
print('-'+ x)
return correct