nestor001 commited on
Commit
73ef4b7
·
verified ·
1 Parent(s): de305ac

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -520
app.py DELETED
@@ -1,520 +0,0 @@
1
- import streamlit as st
2
- import streamlit.components.v1 as components
3
- import pandas as pd
4
- import ifcopenshell
5
- import ifcopenshell.util.element as Element
6
- import tempfile
7
- import plotly.express as px
8
- import plotly.graph_objects as go
9
- import plotly.io as pio
10
- import os
11
- import json
12
- import re
13
- import matplotlib.pyplot as plt
14
- import base64
15
- import pdfkit
16
- import mysql.connector
17
- ##-hola-
18
-
19
- st.set_page_config(page_title="Revisor de Modelos IFC", page_icon="📈")
20
-
21
- st.title("Revisor de Modelos IFC")
22
-
23
- ###---- HIDE STREAMLIT STYLE ----
24
- hide_st_style = """
25
- <style>
26
- #MainMenu {visibility: hidden;}
27
- footer {visibility: hidden;}
28
- header {visibility: hidden;}
29
- </style>
30
- """
31
- st.markdown(hide_st_style, unsafe_allow_html=True)
32
- base="light"
33
-
34
- connection = mysql.connector.connect(
35
- host="srv848.hstgr.io",
36
- user="u539776097_oWm4C",
37
- password="Nekoryu1234.",
38
- database="u539776097_f0Qes"
39
- )
40
-
41
- def cargar_datos_desde_json(tipo_modelo, nivel_avance):
42
- # Genera la ruta completa del archivo JSON basado en la selección del usuario
43
- nombre_archivo = f"{tipo_modelo}_{nivel_avance}.json"
44
- ruta_archivo = os.path.join(nombre_archivo)
45
-
46
- try:
47
- # Intenta abrir y cargar el archivo JSON correspondiente
48
- with open(ruta_archivo, 'r') as file:
49
- data = json.load(file)
50
- return data
51
- except FileNotFoundError:
52
- st.error(f"No existe EAIM para este tipo de modelo.")
53
- return None
54
- except Exception as e:
55
- st.error(f"Error datos")
56
- return None
57
-
58
- def obtener_informacion(data, tipo_modelo, nivel_avance):
59
- if data and tipo_modelo in data and nivel_avance in data[tipo_modelo]:
60
- info_seleccionada = data[tipo_modelo][nivel_avance]
61
- rows = []
62
- for entidad, ndi_info in info_seleccionada.items():
63
- for ndi, ndi_data in ndi_info.items():
64
- atributos = ndi_data.get('Atributos', None)
65
- Propiedades = ndi_data.get('Propiedades', None)
66
-
67
- # Utiliza apply con una función lambda para formatear la columna 'Atributos'
68
- atributos_str = ', '.join(atributos) if atributos else ''
69
-
70
- rows.append([entidad, ndi, atributos_str, Propiedades])
71
-
72
- df = pd.DataFrame(rows, columns=['Entidad', 'NDI', 'Atributos', 'Propiedades'])
73
- return df
74
- else:
75
- return pd.DataFrame({'Mensaje': ['No se encontró información para la selección']})
76
-
77
-
78
- # Crear la aplicación de Streamlit con el tamaño de título personalizado
79
- #st.markdown("<h1 style='text-left: center; font-size: 35px;'>Revisor de Modelos IFC</h1>", unsafe_allow_html=True)
80
-
81
- # Definir las listas de tipos de modelo y niveles de avance
82
- tipos_modelo = ["Sitio", "Volumetrico", "Arquitectura","Estructura",
83
- "Agua caliente","Agua fria","Agua lluvia","Alcantarillado","CCDD","Climatización","Electricidad","Gas","Iluminación","PCI", "Coordinacion"]
84
-
85
- nivel_avance = ["DA", "DB", "DD"]
86
-
87
- # Etiqueta para el tipo de modelo
88
- st.write("Seleccione el tipo de modelo:")
89
- tipo_modelo = st.selectbox("Tipo de Modelo:", tipos_modelo)
90
-
91
- # Etiqueta para el nivel de avance
92
- st.write("Seleccione el EAIM:")
93
- nivel_avance = st.selectbox("EAIM:", nivel_avance)
94
-
95
- data = cargar_datos_desde_json(tipo_modelo, nivel_avance)
96
-
97
- # Agrega un botón de "Aceptar"
98
- if st.button("Aceptar"):
99
- st.write("Entidades, atributos y propiedades minimas de EBPP")
100
- # Código que se ejecutará cuando se presione el botón
101
- resultado_df = obtener_informacion(data, tipo_modelo, nivel_avance)
102
- #st.write(resultado_df) # Muestra el resultado en la aplicación
103
-
104
- resultado_df = obtener_informacion(data, tipo_modelo, nivel_avance)
105
-
106
-
107
- # Crear la aplicación de Streamlit con el tamaño de título personalizado
108
- st.markdown("<h1 style='text-left: center; font-size: 25px;'>Cargar Modelo IFC</h1>", unsafe_allow_html=True)
109
- #st.write("Seleccione y cargue el modelo ifc que desea validar:")
110
-
111
- def get_objects_data_by_class(entity):
112
- psets = Element.get_psets(entity)
113
- attribute_names = [attribute for attribute in dir(entity) if not attribute.startswith("_")]
114
-
115
- # Initialize a dictionary to store properties grouped by Pset name
116
- propiedades_dict = {}
117
-
118
- for pset_name, properties in psets.items():
119
- propiedades = []
120
- for property_name, property_value in properties.items():
121
- if isinstance(property_value, ifcopenshell.entity_instance):
122
- property_value = property_value.Name
123
- propiedades.append(property_name)
124
- propiedades_dict[pset_name] = propiedades
125
-
126
- object_data = {
127
- 'Entidad': entity.is_a(),
128
- 'Atributos': ', '.join(attribute_names),
129
- 'Propiedades': propiedades_dict,
130
- }
131
-
132
- return object_data
133
-
134
- class_type = "IfcRoot" # Change this to the desired class
135
-
136
-
137
- if "file_uploader_key" not in st.session_state:
138
- st.session_state["file_uploader_key"] = 0
139
-
140
- if "uploaded_files" not in st.session_state:
141
- st.session_state["uploaded_files"] = []
142
-
143
- archivo_subido = st.file_uploader(
144
- "Seleccione y cargue el modelo ifc que desea validar:",
145
- type=["ifc"],
146
- key=st.session_state["file_uploader_key"],
147
- )
148
-
149
- if archivo_subido:
150
- st.session_state["uploaded_files"] = [archivo_subido]
151
-
152
- def main():
153
- df_Ifc = None
154
- tmp_filename = None
155
- #archivo_subido = st.file_uploader("Seleccione y cargue el modelo ifc que desea validar:", type=["ifc"])
156
-
157
- if archivo_subido is not None:
158
- with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
159
- tmp_file.write(archivo_subido.read())
160
- tmp_filename = tmp_file.name
161
-
162
- modelo = ifcopenshell.open(tmp_filename)
163
- entity_list = modelo.by_type(class_type) # Use 'class_type' here
164
- entity_data_list = [get_objects_data_by_class(entidad) for entidad in entity_list]
165
-
166
- df = pd.DataFrame(entity_data_list)
167
- df_Ifc = df.drop_duplicates(subset=["Entidad", "Atributos"])
168
-
169
- # Eliminar el archivo temporal
170
- #os.unlink(tmp_filename)
171
- # Return the DataFrame df_Ifc
172
- return df_Ifc
173
-
174
- df_Ifc = main()
175
-
176
-
177
-
178
- # Cargar el primer DataFrame
179
- df1 = resultado_df
180
- #st.write(df1)
181
- # Cargar el segundo DataFrame
182
- df2 = df_Ifc
183
- #st.write(df2)
184
-
185
-
186
- st.markdown("<h1 style='text-left: center; font-size: 25px;'>Iniciar validación</h1>", unsafe_allow_html=True)
187
- st.write("haga click en validar para obtener estadisitcas de cumplimiento de su modelo :")
188
-
189
- # Inicializar un nuevo DataFrame para resumir los resultados
190
- resumen = pd.DataFrame(columns=['Entidad', 'Entidad_existe_si/no', 'Atributos', 'Atributos_existe_si/no'])
191
-
192
- #color del boton validar
193
- def ChangeButtonColour(widget_label, font_color, background_color='transparent'):
194
- htmlstr = f"""
195
- <script>
196
- var elements = window.parent.document.querySelectorAll('button');
197
- for (var i = 0; i < elements.length; ++i) {{
198
- if (elements[i].innerText == '{widget_label}') {{
199
- elements[i].style.color ='{font_color}';
200
- elements[i].style.background = '{background_color}'
201
- }}
202
- }}
203
- </script>
204
- """
205
- components.html(f"{htmlstr}", height=0, width=0)
206
-
207
- ChangeButtonColour("Validar Ifc", "#ffffff", "#ff9317") # button txt to find, colour to assign
208
-
209
- # Crear un botón de validación
210
- if st.button("Validar Ifc"):
211
- st.session_state["file_uploader_key"] += 1
212
- # Revisar las entidades
213
- for entidad in df1['Entidad']:
214
- if entidad in df2['Entidad'].values:
215
- cumple_entidad = 'Si'
216
- else:
217
- cumple_entidad = 'La entidad no existe en el modelo'
218
- row = pd.DataFrame({'Entidad': [entidad], 'Entidad_existe_si/no': [cumple_entidad]})
219
- resumen = pd.concat([resumen, row], ignore_index=True)
220
-
221
- # Revisar los atributos
222
- for entidad, atributos in zip(df1['Entidad'], df1['Atributos']):
223
- if entidad in df2['Entidad'].values:
224
- # Dividir los atributos de df2 en una lista
225
- atributos_df2 = df2[df2['Entidad'] == entidad]['Atributos'].iloc[0].split(", ")
226
-
227
- # Verificar si alguno de los atributos en df1 coincide con los atributos en df2
228
- if any(atributo in atributos_df2 for atributo in atributos.split(', ')):
229
- cumple_atributo = 'Si'
230
-
231
- else:
232
- cumple_atributo = 'No'
233
-
234
- else:
235
- cumple_atributo = 'No' # Si la entidad no existe en df2, los atributos tampoco pueden existir
236
-
237
- resumen.loc[resumen['Entidad'] == entidad, 'Atributos'] = atributos
238
- resumen.loc[resumen['Entidad'] == entidad, 'Atributos_existe_si/no'] = cumple_atributo
239
-
240
- # Rellenar los valores faltantes en el DataFrame de resumen2
241
- resumen.fillna('', inplace=True)
242
-
243
- # Mostrar el resumen de propiedades en Streamlit
244
- st.write("Resultados de Validación de entidades y atributos:")
245
- st.write(resumen)
246
-
247
- # Datos del DataFrame 1
248
- data_df1 = {
249
- 'Entidad': df1['Entidad'],
250
- #'Grupo de Propiedades': df1['Propiedades'].apply(lambda x: set(x.keys())),
251
- 'Propiedades': df1['Propiedades'].apply(lambda x: ', '.join([f'{key}: {value}' for key, value in x.items()]))
252
- }
253
- df1_nuevo = pd.DataFrame(data_df1)
254
-
255
- # Datos del DataFrame 2
256
- data_df2 = {
257
- 'Entidad': df2['Entidad'],
258
- #'Grupo de Propiedades': df2['Propiedades'].apply(lambda x: set(x.keys())),
259
- 'Propiedades': df2['Propiedades'].apply(lambda x: ', '.join([f'{key}: {value}' for key, value in x.items()]))
260
- }
261
- df2_nuevo = pd.DataFrame(data_df2)
262
-
263
- #st.write(df1_nuevo)
264
- #st.write(df2_nuevo)
265
-
266
- # Encontrar grupos que coinciden y que no coinciden
267
- grupos_coinciden = df1_nuevo[df1_nuevo.apply(lambda x: x['Entidad'] in df2_nuevo['Entidad'].values, axis=1)]
268
- grupos_no_coinciden1 = df1_nuevo[~df1_nuevo['Entidad'].isin(df2_nuevo['Entidad'].values)]
269
- #grupos_no_coinciden2 = df2_nuevo[~df2_nuevo['Entidad'].isin(df1_nuevo['Entidad'].values)]
270
- #st.write(grupos_coinciden)
271
- st.write("Propiedades que faltan agregar por entidad")
272
- st.write(grupos_no_coinciden1)
273
-
274
-
275
- propiedades1= grupos_coinciden
276
- propiedades2 = df2_nuevo
277
-
278
- #st.write(propiedades1)
279
- #st.write(propiedades2)
280
-
281
- # Función para extraer grupos y propiedades de la cadena
282
- def extraer_grupos_propiedades(cadena):
283
- grupos_propiedades = re.findall(r"(\w+): \[(.*?)\]", cadena)
284
- resultado = {}
285
- for grupo, propiedades in grupos_propiedades:
286
- resultado[grupo] = propiedades.split(', ')
287
- return resultado
288
-
289
- # Crear una lista para almacenar los datos
290
- data = []
291
-
292
- # Iterar a través de las filas de propiedades1
293
- for index, row in propiedades1.iterrows():
294
- entidad = row['Entidad']
295
- propiedades_grupo1 = extraer_grupos_propiedades(row['Propiedades'])
296
-
297
- # Iterar sobre los grupos y propiedades en el grupo
298
- for grupo, propiedades in propiedades_grupo1.items():
299
- if entidad in propiedades2['Entidad'].values:
300
- propiedades_grupo2 = extraer_grupos_propiedades(propiedades2[propiedades2['Entidad'] == entidad]['Propiedades'].values[0])
301
- coincide_grupo = "Si" if grupo in propiedades_grupo2 else "No"
302
-
303
- propiedades_coinciden = []
304
- for propiedad in propiedades:
305
- if propiedad in propiedades_grupo2.get(grupo, []):
306
- coincide_propiedad = "Si"
307
- else:
308
- coincide_propiedad = "No"
309
- propiedades_coinciden.append((propiedad, coincide_propiedad))
310
- else:
311
- coincide_grupo = "No"
312
- propiedades_coinciden = [(propiedad, "No") for propiedad in propiedades]
313
-
314
- data.extend([(entidad, grupo, coincide_grupo, prop, coincide_prop) for prop, coincide_prop in propiedades_coinciden])
315
-
316
- # Crear el DataFrame
317
- df = pd.DataFrame(data, columns=["Entidad", "Grupo", "Grupo_coincide_si/no_EBPP", "Propiedad", "Propiedad_coincide_si/no_EBPP"])
318
-
319
- st.write("Resultados de Validación: grupos de propiedades y propiedades:")
320
- # Imprimir el DataFrame
321
- st.write(df)
322
-
323
-
324
- # Definir los colores que deseas usar para cada sección
325
- colores = ['#1f77b4', '#ff7f0e'] # Puedes cambiar estos códigos de color según tus preferencias
326
-
327
-
328
- # Crear un DataFrame a partir de resultados_df
329
- resultados_df_dataframe = pd.DataFrame(resumen)
330
-
331
- # Realizar estadísticas simples sobre resultados_df_dataframe
332
- if not resultados_df_dataframe.empty:
333
- st.subheader("Estadísticas sobre los resultados")
334
- num_coincidencias = len(resultados_df_dataframe[resultados_df_dataframe['Entidad_existe_si/no'] == "Si"])
335
- num_diferencias = len(resultados_df_dataframe[resultados_df_dataframe['Entidad_existe_si/no'] == "La entidad no existe en el modelo"])
336
- # Crear un gráfico de anillo con Plotly para las estadísticas globales
337
- anillo = px.pie(
338
- names=["La entidad existe en el modelo", "La entidad no existe en el modelo"],
339
- values=[num_coincidencias, num_diferencias],
340
- hole=0.4, # Controla el tamaño del agujero en el centro del gráfico (0.4 significa un donut)
341
- color_discrete_sequence=colores, # Especifica los colores personalizados aquí
342
- labels={"names": "Estadisitcas del modelo"}
343
- )
344
- # Personalizar el diseño del gráfico
345
- anillo.update_layout(
346
- title='Cumplimiento del modelo según EBPP '
347
- )
348
- # Mostrar el gráfico de anillo en Streamlit
349
- st.plotly_chart(anillo)
350
-
351
-
352
- # Calcular el recuento de cada tipo en 'Entidad_existe_si/no'
353
- counts = resultados_df_dataframe['Entidad_existe_si/no'].value_counts()
354
- # Definir los colores que deseas usar para cada sección
355
- colores = ['#1f77b4', '#ff7f0e'] # Puedes cambiar estos códigos de color según tus preferencias
356
- # Filtrar el DataFrame para obtener los nombres de entidades donde 'Entidad_existe_si/no' es igual a 'Si'
357
- nombres_entidades = resumen[resumen['Entidad_existe_si/no'] == 'Si']['Entidad']
358
- nombres_entidades2 = resumen[resumen['Entidad_existe_si/no'] == 'La entidad no existe en el modelo']['Entidad']
359
- serie_de_nombres = pd.Series(nombres_entidades)
360
- serie_de_nombres2 = pd.Series(nombres_entidades2)
361
- # Concatena los elementos de la serie en un solo texto
362
- texto_concatenado = serie_de_nombres.str.cat(sep=',')
363
- texto_concatenado1 = serie_de_nombres2.str.cat(sep=',')
364
-
365
- # Crear el gráfico de barras personalizado con los valores numéricos encima de las barras y colores personalizados
366
- fig = go.Figure()
367
-
368
- for index, row in counts.items():
369
- color_barra = colores.pop(0) # Obtener el próximo color de la lista
370
- entidad_name = nombres_entidades if index == 'Si' else nombres_entidades2
371
- entidad_name = ', '.join(entidad_name) # Convierte la lista en una cadena separada por comas
372
- fig.add_trace(go.Bar(
373
- x=[index],
374
- y=[row],
375
- text=[row], # Agregar el valor numérico encima de la barra
376
- textposition=['outside'], # Posicionar el valor fuera de la barra
377
- name=str(index), # Usar el valor como etiqueta
378
- marker_color=color_barra # Establecer el color de la barra
379
- ))
380
-
381
- # Personalizar el diseño del gráfico
382
- fig.update_layout(
383
- xaxis_title='Cumplimiento',
384
- yaxis_title='N° de Clases', #[f"{index} ({entidad_name})"]
385
- title='Cumplimiento por Entidades',
386
- yaxis_title_text="N° de Clases"
387
- )
388
-
389
- st.write("Entidades que cumplen: "+texto_concatenado)
390
- st.write("Entidades que no cumplen: "+texto_concatenado1)
391
- # Mostrar el gráfico de barras en Streamlit
392
- #st.plotly_chart(fig)
393
-
394
-
395
- # Crear un DataFrame a partir de resultados_df
396
- df = pd.DataFrame(df)
397
-
398
- # Realizar estadísticas y crear un gráfico de barras apilado con Plotly
399
- fig1 = go.Figure()
400
-
401
- # Agrupar los datos y crear un gráfico de barras apilado
402
- grouped = df.groupby(['Entidad','Grupo_coincide_si/no_EBPP'])['Grupo'].nunique().reset_index(name='Cantidad')
403
- # Obtener los nombres de los grupos para cada entidad
404
- group_names = df.groupby('Entidad')['Grupo'].unique().apply(lambda x: ', '.join(x)).reset_index(name='Grupos')
405
- # Combinar los nombres de los grupos con las cantidades
406
- grouped = pd.merge(grouped, group_names, on='Entidad')
407
- fig1 = px.bar(grouped, x='Entidad', y='Cantidad', color='Grupo_coincide_si/no_EBPP',color_discrete_sequence=['#1f77b4', 'lightblue'],hover_data={'Entidad': False, 'Grupo_coincide_si/no_EBPP': False,'Cantidad': False, 'Grupos': True})
408
-
409
- # Personalizar el diseño del gráfico
410
- fig1.update_layout(
411
- xaxis_title='Entidad',
412
- yaxis_title='Cumplimiento',
413
- title='Cumplimiento de grupos de propiedades por entidades existentes en el modelo',
414
- )
415
-
416
- fig1.update_traces(texttemplate='%{y}', textposition='outside')
417
-
418
- # Mostrar el gráfico con st.plotly_chart en Streamlit
419
- st.plotly_chart(fig1)
420
- st.write("Para mas detalle revise la tabla: grupos de propiedades y propiedades la columna'Grupo'")
421
-
422
- # Crear un DataFrame a partir de resultados_df
423
- df = pd.DataFrame(df)
424
-
425
- # Realizar estadísticas y crear un gráfico de barras apilado con Plotly
426
- barra_propiedades = go.Figure()
427
-
428
- # Agrupar los datos y crear un gráfico de barras apilado
429
- grouped = df.groupby(['Grupo', 'Propiedad_coincide_si/no_EBPP']).size().reset_index(name='Cantidad')
430
- group_names = df.groupby('Grupo')['Propiedad'].apply(lambda x: '\n'.join(x)).reset_index(name='Propiedad')
431
- grouped = pd.merge(grouped, group_names, on='Grupo')
432
- barra_propiedades = px.bar(grouped, x='Grupo', y='Cantidad', color='Propiedad_coincide_si/no_EBPP',color_discrete_sequence=['#1f77b4', 'lightblue'],hover_data={'Grupo': False, 'Cantidad': False,'Propiedad_coincide_si/no_EBPP': False, 'Propiedad': True})
433
-
434
-
435
- # Personalizar el diseño del gráfico
436
- barra_propiedades.update_layout(
437
- xaxis_title='Entidad',
438
- yaxis_title='Cumplimiento',
439
- title='Cumplimiento propiedades por grupo de propiedades',
440
- )
441
-
442
- # Agregar el valor numérico encima de cada barra
443
- barra_propiedades.update_traces(texttemplate='%{y}', textposition='inside')
444
-
445
- # Mostrar el gráfico con st.plotly_chart en Streamlit
446
- st.plotly_chart(barra_propiedades)
447
- st.write("Para mas detalle revise la tabla: grupos de propiedades y propiedades la columna'Propiedad'")
448
-
449
-
450
- # Crear un escritor Excel para guardar los DataFrames en hojas diferentes
451
- with pd.ExcelWriter('resultados_validacion.xlsx', engine='xlsxwriter') as writer:
452
- resumen.to_excel(writer, sheet_name='Resumen_entidades')
453
- df.to_excel(writer, sheet_name='Resumen_Propiedades')
454
- grupos_no_coinciden1.to_excel(writer, sheet_name='entidades_propiedades_faltantes')
455
- ChangeButtonColour("Terminar validación", "#ffffff", "#ff9317")
456
- if st.button("Terminar validación"):
457
- #st.session_state["file_uploader_key"] += 1
458
- st.experimental_rerun()
459
-
460
-
461
- def main():
462
- # Editar el tamaño del título principal aquí
463
- size_titulo_principal = "20px" # Tamaño deseado del título principal
464
-
465
- # Aplicar el tamaño del título principal utilizando Markdown y CSS
466
- st.markdown(f"<h1 style='font-size:{size_titulo_principal}'>Cuestionario de Evaluación del Proyecto</h1>", unsafe_allow_html=True)
467
-
468
- respuestas = {}
469
-
470
- # Tamaño de los títulos y las preguntas
471
- st.markdown(f"<h1 style='font-size:{20}px'>I. Funcionalidad General</h1>", unsafe_allow_html=True)
472
-
473
- tiempo_procesamiento = st.radio("¿Cuál es el tiempo promedio de procesamiento por cada modelo BIM representativo en formato IFC?",
474
- options=["a) Entre 1 y 5 minutos", "b) Entre 5 y 10 minutos", "c) Más de 10 minutos"])
475
- respuestas["tiempo_procesamiento"] = tiempo_procesamiento
476
-
477
- st.markdown(f"<h1 style='font-size:{20}px'>II. Operacionabilidad</h1>", unsafe_allow_html=True)
478
- tiempo_ejecucion = st.radio("¿Cuánto tiempo promedio tarda en ejecutar el flujo de trabajo completo (revisión de modelos BIM IFC y emisión de reportes de gestión?",
479
- options=["a) Menos de 5 minutos", "b) Entre 5 y 10 minutos", "c) Más de 10 minutos"])
480
- respuestas["tiempo_ejecucion"] = tiempo_ejecucion
481
-
482
- st.markdown(f"<h1 style='font-size:{20}px'>III. Confianza en los Resultados</h1>", unsafe_allow_html=True)
483
- concordancia_revisiones = st.radio("¿Cuál es el porcentaje de precisión en la cantidad de parámetros IFC que se revisan automatizadamente en comparación con revisiones manuales?",
484
- options=["a) Más del 90%", "b) Entre 70% y 90%", "c) Menos del 70%"])
485
- respuestas["concordancia_revisiones"] = concordancia_revisiones
486
-
487
- st.markdown(f"<h1 style='font-size:{20}px'>IV. Compatibilidad con SDI BIM</h1>", unsafe_allow_html=True)
488
- cumplimiento_requisitos = st.radio("¿Cuál es el tiempo promedio de carga de los modelos BIM en formato IFC de prueba?",
489
- options=["a) Cumple totalmente", "b) Cumple parcialmente", "c) No cumple"])
490
- respuestas["cumplimiento_requisitos"] = cumplimiento_requisitos
491
-
492
- st.markdown(f"<h1 style='font-size:{20}px'>V. Tiempo de Respuesta</h1>", unsafe_allow_html=True)
493
- tiempo_respuesta = st.radio("¿Cuál es el tiempo promedio de respuesta del sistema en modelos de prueba?",
494
- options=["a) Menos de 1 minuto", "b) Entre 1 y 3 minutos", "c) Más de 3 minutos"])
495
- respuestas["tiempo_respuesta"] = tiempo_respuesta
496
-
497
- st.markdown(f"<h1 style='font-size:{20}px'>VI. Interoperabilidad</h1>", unsafe_allow_html=True)
498
- problemas_interoperabilidad = st.radio("¿Cuántos problemas de uso de la plataforma web se han identificado y resuelto durante el mes en curso?",
499
- options=["a) Más de 5", "b) Entre 2 y 5", "c) Menos de 2"])
500
- respuestas["problemas_interoperabilidad"] = problemas_interoperabilidad
501
-
502
- # Mostrar respuestas al finalizar el cuestionario
503
- if st.button("Finalizar cuestionario"):
504
- # Generar insercion de base datos
505
- cursor2 = connection.cursor()
506
-
507
- insert_KPI = "INSERT INTO `TablaKPI`(`DIRECCION`, `TiempoPromedioProceso`, `TiempoPromedioEjecucion`, `PorcentajeConcordancia`, `CumpleRequisitosSDO`, `TiempoPromedioRespuesta`, `ProblemaInteroperabilidad`) VALUES (%s,%s,%s,%s,%s,%s,%s)"
508
- cursor2.execute(insert_KPI,("DA", tiempo_procesamiento , tiempo_ejecucion , concordancia_revisiones , cumplimiento_requisitos , tiempo_respuesta , problemas_interoperabilidad ))
509
- connection.commit()
510
-
511
- # Generar el enlace para descargar el archivo Excel
512
- with open('resultados_validacion.xlsx', 'rb') as f:
513
- excel_data = f.read()
514
- b64 = base64.b64encode(excel_data).decode()
515
- href = f'<a href="data:file/excel;base64,{b64}" download="resultados_validacion.xlsx">Descargar Resultados de Validación (Excel)</a>'
516
- st.markdown(href, unsafe_allow_html=True)
517
-
518
-
519
- if __name__ == "__main__":
520
- main()