Spaces:
Build error
Build error
Download app.py from Rajor78/codificacion: direct link, hf CLI and curl.
- Browser
- Download file 5.86 kB
-
https://huggingface.co/spaces/Rajor78/codificacion/resolve/main/app.py
- Command line
-
hf download hf://spaces/Rajor78/codificacion/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Rajor78/codificacion/resolve/main/app.py
5.86 kB
| import gradio as gr | |
| import pandas as pd | |
| from typing import Dict, List, Tuple | |
| from openpyxl.styles import PatternFill, Font | |
| from openpyxl.utils import get_column_letter | |
| from datetime import datetime | |
| def create_encoding_dict(training_df: pd.DataFrame) -> Dict[str, List[str]]: | |
| """ | |
| Crea un diccionario de codificaci贸n basado en el DataFrame de entrenamiento. | |
| Las respuestas pueden tener m煤ltiples c贸digos separados por punto y coma. | |
| """ | |
| encoding_dict = {} | |
| for _, row in training_df.iterrows(): | |
| respuesta = str(row['B']).strip().lower() | |
| codigos = str(row['C']).strip().split(';') | |
| codigos = [codigo.strip() for codigo in codigos] | |
| encoding_dict[respuesta] = codigos | |
| return encoding_dict | |
| def find_best_match(respuesta: str, encoding_dict: Dict[str, List[str]]) -> Tuple[List[str], float, str]: | |
| """ | |
| Encuentra la mejor coincidencia para una respuesta en el diccionario de codificaci贸n. | |
| Retorna los c贸digos correspondientes, el score de similitud y la respuesta que hizo match. | |
| """ | |
| from difflib import SequenceMatcher | |
| respuesta = respuesta.strip().lower() | |
| if respuesta in encoding_dict: | |
| return encoding_dict[respuesta], 1.0, respuesta | |
| best_score = 0 | |
| best_match = None | |
| for known_resp in encoding_dict.keys(): | |
| score = SequenceMatcher(None, respuesta, known_resp).ratio() | |
| if score > best_score: | |
| best_score = score | |
| best_match = known_resp | |
| if best_score > 0.8: | |
| return encoding_dict[best_match], best_score, best_match | |
| return [], 0.0, "" | |
| def format_excel(writer, df, sheet_name="Resultados"): | |
| """ | |
| Da formato al archivo Excel de salida | |
| """ | |
| # Escribimos el DataFrame en el Excel | |
| df.to_excel(writer, sheet_name=sheet_name, index=False) | |
| # Obtenemos la hoja de trabajo | |
| workbook = writer.book | |
| worksheet = writer.sheets[sheet_name] | |
| # Definimos los estilos | |
| header_fill = PatternFill(start_color='366092', end_color='366092', fill_type='solid') | |
| header_font = Font(color='FFFFFF', bold=True) | |
| # Formato para los encabezados | |
| for col in range(len(df.columns)): | |
| cell = worksheet.cell(row=1, column=col+1) | |
| cell.fill = header_fill | |
| cell.font = header_font | |
| # Ajustamos el ancho de las columnas | |
| for col in range(len(df.columns)): | |
| max_length = 0 | |
| column = get_column_letter(col + 1) | |
| for cell in worksheet[column]: | |
| try: | |
| if len(str(cell.value)) > max_length: | |
| max_length = len(str(cell.value)) | |
| except: | |
| pass | |
| adjusted_width = (max_length + 2) | |
| worksheet.column_dimensions[column].width = min(adjusted_width, 50) | |
| def process_excel(training_file, new_file): | |
| """ | |
| Procesa los archivos de Excel y codifica las nuevas respuestas. | |
| """ | |
| try: | |
| # Leemos los archivos | |
| training_df = pd.read_excel(training_file.name) | |
| new_df = pd.read_excel(new_file.name) | |
| # Creamos el diccionario de codificaci贸n | |
| encoding_dict = create_encoding_dict(training_df) | |
| # Preparamos las columnas de resultado | |
| results_df = new_df.copy() | |
| results_df['C贸digos_Asignados'] = '' | |
| results_df['Score_Similitud'] = 0.0 | |
| results_df['Respuesta_Match'] = '' | |
| results_df['Fecha_Proceso'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
| # Procesamos cada respuesta nueva | |
| for idx, row in results_df.iterrows(): | |
| respuesta = str(row['B']) | |
| codigos, score, match = find_best_match(respuesta, encoding_dict) | |
| results_df.at[idx, 'C贸digos_Asignados'] = '; '.join(codigos) if codigos else 'SIN_MATCH' | |
| results_df.at[idx, 'Score_Similitud'] = round(score, 2) | |
| results_df.at[idx, 'Respuesta_Match'] = match if match else 'N/A' | |
| # Creamos un resumen | |
| total_respuestas = len(results_df) | |
| respuestas_codificadas = len(results_df[results_df['C贸digos_Asignados'] != 'SIN_MATCH']) | |
| summary_df = pd.DataFrame({ | |
| 'M茅trica': ['Total Respuestas', 'Respuestas Codificadas', 'Respuestas Sin Match', 'Porcentaje Codificaci贸n'], | |
| 'Valor': [ | |
| total_respuestas, | |
| respuestas_codificadas, | |
| total_respuestas - respuestas_codificadas, | |
| f"{(respuestas_codificadas/total_respuestas*100):.1f}%" | |
| ] | |
| }) | |
| # Guardamos el resultado en un Excel con m煤ltiples hojas | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| output_path = f"resultados_codificacion_{timestamp}.xlsx" | |
| with pd.ExcelWriter(output_path, engine='openpyxl') as writer: | |
| # Hoja de resultados detallados | |
| format_excel(writer, results_df, "Resultados") | |
| # Hoja de resumen | |
| format_excel(writer, summary_df, "Resumen") | |
| # Hoja con datos de entrenamiento | |
| format_excel(writer, training_df, "Datos_Entrenamiento") | |
| return output_path | |
| except Exception as e: | |
| return f"Error: {str(e)}" | |
| # Creamos la interfaz de Gradio | |
| iface = gr.Interface( | |
| fn=process_excel, | |
| inputs=[ | |
| gr.File(label="Archivo de entrenamiento (Excel)"), | |
| gr.File(label="Archivo a codificar (Excel)") | |
| ], | |
| outputs=gr.File(label="Archivo de resultados"), | |
| title="Codificador de Respuestas", | |
| description="Sube un archivo Excel de entrenamiento (con c贸digos conocidos) y un archivo nuevo para codificar las respuestas.", | |
| examples=[], | |
| cache_examples=False | |
| ) | |
| # Iniciamos la aplicaci贸n | |
| if __name__ == "__main__": | |
| iface.launch() |