diff --git a/action_flow/fase1_extract.py b/action_flow/fase1_extract.py index 4bc0e12..269478f 100644 --- a/action_flow/fase1_extract.py +++ b/action_flow/fase1_extract.py @@ -30,34 +30,36 @@ FILES_TO_PROCESS = os.listdir(INPUT_FOLDER) DELIMITER = "|^" DIC_QUESTIONS = { "Encuesta_MediaG01Q02.csv": agentes_entidades.extractor_pre_1, - "Encuesta_MediaG01Q04.csv": agentes_entidades.extractor_pre_2, - "Encuesta_MediaG01Q10.csv": agentes_entidades.extractor_pre_3, - "Encuesta_MediaG03Q17.csv": agentes_entidades.extractor_pre_4, - "Encuesta_MediaG03Q18.csv": agentes_entidades.extractor_pre_5, - # "Encuesta_MediaG03Q19.csv": agentes_entidades.extractor_pre_6, - "Encuesta_MediaG04Q22.csv": agentes_entidades.extractor_pre_7, - "Encuesta_MediaG04Q23.csv": agentes_entidades.extractor_pre_8, - "Encuesta_MediaG04Q25.csv": agentes_entidades.extractor_pre_9, - "Encuesta_MediaG05Q30.csv": agentes_entidades.extractor_pre_10, - "Encuesta_MediaG05Q34.csv": agentes_entidades.extractor_pre_11, - "Encuesta_MediaG05Q28.csv": agentes_entidades.extractor_pre_12, - "Encuesta_MediaG06Q35.csv": agentes_entidades.extractor_pre_13, - "Encuesta_MediaG06Q38.csv": agentes_entidades.extractor_pre_14, - "Encuesta_MediaG06Q40.csv": agentes_entidades.extractor_pre_15, + # "Encuesta_MediaG01Q04.csv": agentes_entidades.extractor_pre_2, + # "Encuesta_MediaG01Q10.csv": agentes_entidades.extractor_pre_3, + # "Encuesta_MediaG03Q17.csv": agentes_entidades.extractor_pre_4, + # "Encuesta_MediaG03Q18.csv": agentes_entidades.extractor_pre_5, + # # "Encuesta_MediaG03Q19.csv": agentes_entidades.extractor_pre_6, + # "Encuesta_MediaG04Q22.csv": agentes_entidades.extractor_pre_7, + # "Encuesta_MediaG04Q23.csv": agentes_entidades.extractor_pre_8, + # "Encuesta_MediaG04Q25.csv": agentes_entidades.extractor_pre_9, + # "Encuesta_MediaG05Q30.csv": agentes_entidades.extractor_pre_10, + # "Encuesta_MediaG05Q34.csv": agentes_entidades.extractor_pre_11, + # "Encuesta_MediaG05Q28.csv": agentes_entidades.extractor_pre_12, + # "Encuesta_MediaG06Q35.csv": agentes_entidades.extractor_pre_13, + # "Encuesta_MediaG06Q38.csv": agentes_entidades.extractor_pre_14, + # "Encuesta_MediaG06Q40.csv": agentes_entidades.extractor_pre_15, } -# 2. Refactorizar 'extract_answers' para manejar todos los tipos de esquemas def extract_answers(answers_obj): """ - Toma el objeto Pydantic devuelto por un extractor y lo formatea - en un único string delimitado por |^. - """ - answer_formated = "" - list_items = [] # Lista genérica de items (ej. [Accion, Accion]) - item_attr_name = "" # Atributo a extraer de cada item (ej. "accion") + Toma el objeto Pydantic devuelto por un extractor y devuelve + una LISTA de los textos de respuesta extraídos. - # --- Manejo de todos los esquemas que son listas de objetos --- + Devuelve: + list[str]: Una lista de strings (ej. ["Accion 1", "Accion 2"]) + """ + list_items_text = [] # Lista para guardar solo los strings finales + list_items = [] # Lista genérica de objetos + item_attr_name = "" # Atributo a extraer + + # --- Manejo de esquemas de listas de objetos --- if isinstance(answers_obj, Acciones): list_items = answers_obj.acciones @@ -87,55 +89,128 @@ def extract_answers(answers_obj): list_items = answers_obj.expectativas item_attr_name = "expectativa" - # Si se encontró un tipo de lista estándar, procesarla if list_items and item_attr_name: for item in list_items: - # Obtener el texto (ej. item.accion, item.tema) de forma segura item_text = getattr(item, item_attr_name, "") if item_text: - answer_formated += f"{item_text}{DELIMITER}" - return answer_formated + list_items_text.append(item_text) + return list_items_text # Devuelve la lista de textos # --- Manejo del caso especial: Competencias --- - if isinstance(answers_obj, Competencias): - comp_texts = [] - # El esquema de Competencias usa listas de strings, no listas de objetos + elif isinstance(answers_obj, Competencias): if answers_obj.basicas: - comp_texts.extend([f"Básica: {c}" for c in answers_obj.basicas]) + list_items_text.extend([f"Básica: {c}" for c in answers_obj.basicas if c]) if answers_obj.socioemocionales: - comp_texts.extend( - [f"Socioemocional: {c}" for c in answers_obj.socioemocionales] + list_items_text.extend( + [f"Socioemocional: {c}" for c in answers_obj.socioemocionales if c] ) if answers_obj.ciudadanas: - comp_texts.extend([f"Ciudadana: {c}" for c in answers_obj.ciudadanas]) + list_items_text.extend( + [f"Ciudadana: {c}" for c in answers_obj.ciudadanas if c] + ) if answers_obj.siglo_xxi: - comp_texts.extend([f"Siglo XXI: {c}" for c in answers_obj.siglo_xxi]) + list_items_text.extend( + [f"Siglo XXI: {c}" for c in answers_obj.siglo_xxi if c] + ) + return list_items_text # Devuelve la lista de textos de competencias - if not comp_texts: - return "" # Devuelve vacío si el objeto Competencias está vacío - - # Unir todos los textos de competencias - answer_formated = DELIMITER.join(comp_texts) + DELIMITER - return answer_formated - - # Si el tipo no coincide con nada (o era una lista vacía), devuelve un string vacío - return answer_formated + # Si no se encontró nada, devuelve una lista vacía + return [] def format_answer(dataframe, function): + """ + Itera sobre el dataframe, aplica la función extractora y gestiona + el contador de IDs global para ESE dataframe. + """ dataframe["respuestas_formato"] = None + dataframe["respuestas_formato_id"] = None + + # Inicializar el contador de ID global para este archivo + global_id_counter = 1 + for index, row in dataframe.iterrows(): + # 1. Obtener el objeto Pydantic answers = function(row["respuesta"]) - answer_to_insert = extract_answers(answers) - dataframe.loc[index, "respuestas_formato"] = answer_to_insert + + # 2. Obtener la LISTA de textos extraídos + list_items_text = extract_answers(answers) + + # 3. Si la lista está vacía, poner strings vacíos y continuar + if not list_items_text: + dataframe.loc[index, "respuestas_formato"] = "" + dataframe.loc[index, "respuestas_formato_id"] = "" + continue # No incrementa el contador + + # 4. Si hay textos, formatear la salida + count = len(list_items_text) + + # Formatear el texto + answer_formated = DELIMITER.join(list_items_text) + DELIMITER + + # Formatear los IDs usando el contador global + id_list = [str(i) for i in range(global_id_counter, global_id_counter + count)] + id_formated = ",".join(id_list) + + # 5. Asignar los valores al DataFrame + dataframe.loc[index, "respuestas_formato"] = answer_formated + dataframe.loc[index, "respuestas_formato_id"] = id_formated + + # 6. Actualizar el contador global para la siguiente fila + global_id_counter += count def format_all_answers(Dic_questions): + """ + Función principal que procesa todos los archivos CSV definidos en Dic_questions. + """ for key, value in Dic_questions.items(): - question_dataframe = pd.read_csv(INPUT_FOLDER + "/" + key) - format_answer(question_dataframe, value) - question_dataframe.to_csv(OUTPUT_FOLDER + "/" + key) + try: + # Construir la ruta completa al archivo de entrada + input_file_path = os.path.join(INPUT_FOLDER, key) + + # Verificar si el archivo existe + if not os.path.exists(input_file_path): + print(f"Advertencia: El archivo no existe, omitiendo: {key}") + continue + + question_dataframe = pd.read_csv(input_file_path) + + if question_dataframe.empty: + print(f"Archivo vacío, omitiendo: {key}") + continue + + if "respuesta" not in question_dataframe.columns: + print(f"No se encontró la columna 'respuesta' en {key}, omitiendo.") + continue + + # Esta función ahora maneja toda la lógica de conteo + format_answer(question_dataframe, value) + + # Limpiar NAs antes de guardar + question_dataframe["respuestas_formato"] = question_dataframe[ + "respuestas_formato" + ].fillna("") + question_dataframe["respuestas_formato_id"] = question_dataframe[ + "respuestas_formato_id" + ].fillna("") + + # Construir la ruta completa al archivo de salida + output_file_path = os.path.join(OUTPUT_FOLDER, key) + + # Asegurarse de que el directorio de salida exista + os.makedirs(OUTPUT_FOLDER, exist_ok=True) + + question_dataframe.to_csv(output_file_path, index=False) + print(f"Procesado y guardado: {key}") + + except pd.errors.EmptyDataError: + print(f"Error: El archivo {key} está vacío o es inválido.") + except Exception as e: + print(f"Error inesperado procesando {key}: {e}") +# --- Ejecutar el proceso --- format_all_answers(DIC_QUESTIONS) +print("Proceso de Fase 1 completado.") diff --git a/input/Preguntas Categoricas/Encuesta_MediaG01Q02.csv b/input/Preguntas Categoricas/Encuesta_MediaG01Q02.csv index 582e18f..7afd8de 100644 --- a/input/Preguntas Categoricas/Encuesta_MediaG01Q02.csv +++ b/input/Preguntas Categoricas/Encuesta_MediaG01Q02.csv @@ -1,2 +1,3 @@ cod_dane,cod_pregunta,respuesta 205120000366/I.E. AURELIO MEJIA,G01Q02,"Realiza promoción por radio, mensajes informativos en porteria y carteleras del plantel, voz a voz con la comunidad educativa" +205120000366/I.E. AURELIO MEJIA,G01Q02,"Realiza promoción por radio, mensajes informativos en porteria y carteleras del plantel, voz a voz con la comunidad educativa" diff --git a/output/fase1/.~lock.Encuesta_MediaG01Q02.csv# b/output/fase1/.~lock.Encuesta_MediaG01Q02.csv# index 9a925a7..04a98e6 100644 --- a/output/fase1/.~lock.Encuesta_MediaG01Q02.csv# +++ b/output/fase1/.~lock.Encuesta_MediaG01Q02.csv# @@ -1 +1 @@ -,mongar,mongar,13.11.2025 14:35,file:///home/mongar/.config/libreoffice/4; \ No newline at end of file +,mongar,mongar,14.11.2025 16:57,file:///home/mongar/.config/libreoffice/4; \ No newline at end of file diff --git a/output/fase1/.~lock.Encuesta_MediaG06Q40.csv# b/output/fase1/.~lock.Encuesta_MediaG06Q40.csv# deleted file mode 100644 index 690340e..0000000 --- a/output/fase1/.~lock.Encuesta_MediaG06Q40.csv# +++ /dev/null @@ -1 +0,0 @@ -,mongar,mongar,14.11.2025 14:50,file:///home/mongar/.config/libreoffice/4; \ No newline at end of file diff --git a/output/fase1/Encuesta_MediaG01Q02.csv b/output/fase1/Encuesta_MediaG01Q02.csv index 33d7352..67f0cfd 100644 --- a/output/fase1/Encuesta_MediaG01Q02.csv +++ b/output/fase1/Encuesta_MediaG01Q02.csv @@ -1,2 +1,3 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120000366/I.E. AURELIO MEJIA,G01Q02,"Realiza promoción por radio, mensajes informativos en porteria y carteleras del plantel, voz a voz con la comunidad educativa",Realiza promoción por radio para informar a la comunidad sobre el acceso a educación media.|^Difunde mensajes informativos en la portería del establecimiento educativo.|^Utiliza carteleras del plantel para comunicar información sobre acceso a educación media.|^Implementa estrategia de comunicación de voz a voz con la comunidad educativa para promover el acceso a educación media.|^ +cod_dane,cod_pregunta,respuesta,respuestas_formato,respuestas_formato_id +205120000366/I.E. AURELIO MEJIA,G01Q02,"Realiza promoción por radio, mensajes informativos en porteria y carteleras del plantel, voz a voz con la comunidad educativa",Realiza promoción por radio para informar a la comunidad sobre el acceso a educación media.|^Difunde mensajes informativos en la portería del establecimiento educativo.|^Utiliza carteleras del plantel para comunicar información sobre acceso a educación media.|^Implementa estrategia de comunicación de voz a voz con la comunidad educativa para promover el acceso a educación media.|^,"1,2,3,4" +205120000366/I.E. AURELIO MEJIA,G01Q02,"Realiza promoción por radio, mensajes informativos en porteria y carteleras del plantel, voz a voz con la comunidad educativa",Realiza promoción por radio para informar a la comunidad sobre el acceso a educación media.|^Difunde mensajes informativos en la portería del establecimiento educativo.|^Utiliza carteleras del plantel para comunicar información sobre acceso a educación media.|^Implementa estrategia de comunicación de voz a voz con la comunidad educativa para promover el acceso a educación media.|^,"5,6,7,8" diff --git a/output/fase1/Encuesta_MediaG01Q04.csv b/output/fase1/Encuesta_MediaG01Q04.csv index 26664b4..a4e968b 100644 --- a/output/fase1/Encuesta_MediaG01Q04.csv +++ b/output/fase1/Encuesta_MediaG01Q04.csv @@ -1,2 +1,2 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120000366/I.E. AURELIO MEJIA,G01Q04,Continuamente hacer encuestas de satisfacción para conocer las inquietudes y deseos que tienen nuestros estudiantes. También se ofrecen talleres de nivelación para aquellos que presentan dificultades en el rendimiento,Realizan encuestas de satisfacción de forma continua para conocer las inquietudes y deseos de los estudiantes.|^Ofrecen talleres de nivelación para estudiantes que presentan dificultades en el rendimiento académico.|^ +cod_dane,cod_pregunta,respuesta,respuestas_formato,respuestas_formato_id +205120000366/I.E. AURELIO MEJIA,G01Q04,Continuamente hacer encuestas de satisfacción para conocer las inquietudes y deseos que tienen nuestros estudiantes. También se ofrecen talleres de nivelación para aquellos que presentan dificultades en el rendimiento,Realizan encuestas de satisfacción de forma continua para conocer las inquietudes y deseos de los estudiantes.|^Ofrecen talleres de nivelación para estudiantes que presentan dificultades en el rendimiento académico.|^,"1,2" diff --git a/output/fase1/Encuesta_MediaG01Q10.csv b/output/fase1/Encuesta_MediaG01Q10.csv deleted file mode 100644 index 29f6dec..0000000 --- a/output/fase1/Encuesta_MediaG01Q10.csv +++ /dev/null @@ -1,2 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120000366/I.E. AURELIO MEJIA,G01Q10,"Desde hace ya mas de tres años no se actualizaba el PEI, se incluyó el tema de los ajustes razonables y se reorganizó los principios instritucionales",Actualización del Proyecto Educativo Institucional (PEI) después de más de tres años sin actualización|^Inclusión del tema de ajustes razonables en la transformación curricular|^Reorganización de los principios institucionales|^ diff --git a/output/fase1/Encuesta_MediaG03Q17.csv b/output/fase1/Encuesta_MediaG03Q17.csv deleted file mode 100644 index 2a14f0b..0000000 --- a/output/fase1/Encuesta_MediaG03Q17.csv +++ /dev/null @@ -1,2 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120000366/I.E. AURELIO MEJIA,G03Q17,"PIAR, STEAM,+H y tecnologías",PIAR (Planes Individualizados de Ajustes Razonables)|^STEAM|^Humanidades (+H)|^Tecnologías|^ diff --git a/output/fase1/Encuesta_MediaG03Q18.csv b/output/fase1/Encuesta_MediaG03Q18.csv deleted file mode 100644 index 8427e16..0000000 --- a/output/fase1/Encuesta_MediaG03Q18.csv +++ /dev/null @@ -1,2 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120000366/I.E. AURELIO MEJIA,G03Q18,Generalmente la encuesta en linea,Realizar encuestas en línea para identificar las necesidades de formación del equipo docente.|^ diff --git a/output/fase1/Encuesta_MediaG04Q22.csv b/output/fase1/Encuesta_MediaG04Q22.csv deleted file mode 100644 index 90ae122..0000000 --- a/output/fase1/Encuesta_MediaG04Q22.csv +++ /dev/null @@ -1,2 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120001435/I.E. GASPAR DE RODAS,G04Q22,l la participación de los padres de familia y los estudiantes por lo tanto como estrategia principal esta que ellos participen dando la información de que hay cupos para educación media creando material informativo y que sean los encargados de la distribución en sus barrios,Promover la participación de padres de familia y estudiantes en la difusión de información sobre cupos disponibles en educación media.|^Crear material informativo sobre la disponibilidad de cupos para educación media.|^Encargar a padres de familia y estudiantes la distribución del material informativo en sus barrios.|^ diff --git a/output/fase1/Encuesta_MediaG04Q23.csv b/output/fase1/Encuesta_MediaG04Q23.csv deleted file mode 100644 index 524c6c2..0000000 --- a/output/fase1/Encuesta_MediaG04Q23.csv +++ /dev/null @@ -1,3 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120001435/I.E. GASPAR DE RODAS,G04Q23,"A nivel social y económico, el comercio en la zona necesita mano de obra barata y los estudiantes prefieren ir a trabajar asi sea por poco dinero pero tener algo con que sobrevivir. -A nivel cultural en las familias son pocos los bachilleres que hay entonces terminar no es motivación",La demanda de mano de obra barata por parte del comercio local que atrae a los estudiantes a trabajar por poco dinero para sobrevivir.|^La baja escolaridad en las familias (pocos bachilleres) que genera falta de motivación para terminar la educación media.|^ diff --git a/output/fase1/Encuesta_MediaG04Q25.csv b/output/fase1/Encuesta_MediaG04Q25.csv deleted file mode 100644 index 0001bf2..0000000 --- a/output/fase1/Encuesta_MediaG04Q25.csv +++ /dev/null @@ -1,2 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120001435/I.E. GASPAR DE RODAS,G04Q25,, diff --git a/output/fase1/Encuesta_MediaG05Q28.csv b/output/fase1/Encuesta_MediaG05Q28.csv deleted file mode 100644 index 171c974..0000000 --- a/output/fase1/Encuesta_MediaG05Q28.csv +++ /dev/null @@ -1,2 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120001435/I.E. GASPAR DE RODAS,G05Q28,"En la última actualización del PEI intentamos que muchos de los temas de clase tengan como eje las problemáticas del territorio para que ellos analicen y de forma critican generen propuestas, sin embargo algunos profesores aún están reacios a cambiar la metodología",En la última actualización del PEI se intentó que muchos temas de clase tengan como eje las problemáticas del territorio.|^Se busca que los estudiantes analicen críticamente las problemáticas del territorio y generen propuestas.|^Algunos profesores aún están reacios a cambiar la metodología necesaria para implementar estos cambios.|^ diff --git a/output/fase1/Encuesta_MediaG05Q30.csv b/output/fase1/Encuesta_MediaG05Q30.csv deleted file mode 100644 index c6bfb2f..0000000 --- a/output/fase1/Encuesta_MediaG05Q30.csv +++ /dev/null @@ -1,2 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120001435/I.E. GASPAR DE RODAS,G05Q30,"La empatía, trabajo en equipo y se trabaja de manera muy fuerte las competencias matemáticas",Básica: Matemáticas|^Socioemocional: Empatía|^Socioemocional: Trabajo en equipo|^ diff --git a/output/fase1/Encuesta_MediaG05Q34.csv b/output/fase1/Encuesta_MediaG05Q34.csv deleted file mode 100644 index 6a6e4d7..0000000 --- a/output/fase1/Encuesta_MediaG05Q34.csv +++ /dev/null @@ -1,2 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120001435/I.E. GASPAR DE RODAS,G05Q34,Rubricas de evaluación por áreas de conocimiento y listas de chequeo de acuerdo a las dimensiones del desarrollo con el grado de transición,Rúbricas de evaluación por áreas de conocimiento|^Listas de chequeo de acuerdo a las dimensiones del desarrollo|^ diff --git a/output/fase1/Encuesta_MediaG06Q35.csv b/output/fase1/Encuesta_MediaG06Q35.csv deleted file mode 100644 index 0b4904b..0000000 --- a/output/fase1/Encuesta_MediaG06Q35.csv +++ /dev/null @@ -1,2 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120001435/I.E. GASPAR DE RODAS,G06Q35,Son muy altas pues desde hace varios años hemos venido solicitando el apoyo de dicha institución para que nos colabore con recursos,Recibir apoyo de la institución con recursos para el fortalecimiento de la educación media|^ diff --git a/output/fase1/Encuesta_MediaG06Q38.csv b/output/fase1/Encuesta_MediaG06Q38.csv deleted file mode 100644 index baf3c11..0000000 --- a/output/fase1/Encuesta_MediaG06Q38.csv +++ /dev/null @@ -1,2 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120001435/I.E. GASPAR DE RODAS,G06Q38,"Las veces que han dado charlas son mas que todo para motivarlos a que sigan en educación superior y ellos desean aprender herramientas tecnológicas para sus emprendimientos familiares o propios, pocos quieren seguir estudiando","Las charlas de la Secretaría de Educación se enfocan principalmente en motivar a los estudiantes a continuar con educación superior.|^Los estudiantes desean aprender herramientas tecnológicas para sus emprendimientos familiares o propios, más que continuar estudiando.|^Pocos estudiantes desean seguir estudiando después de las charlas de motivación ofrecidas.|^" diff --git a/output/fase1/Encuesta_MediaG06Q40.csv b/output/fase1/Encuesta_MediaG06Q40.csv deleted file mode 100644 index 777797c..0000000 --- a/output/fase1/Encuesta_MediaG06Q40.csv +++ /dev/null @@ -1,2 +0,0 @@ -,cod_dane,cod_pregunta,respuesta,respuestas_formato -0,205120001435/I.E. GASPAR DE RODAS,G06Q40,"Comparte mucha información de las alianzas que se han logrado pero en nuestra subregión no hay nada, todo es para el oriente ","La Secretaría de Educación comparte información sobre alianzas, pero estas no llegan a la subregión.|^Los beneficios y apoyos de la Secretaría se concentran en la región del oriente, dejando fuera a otras subregiones.|^Existe una falta de coherencia en la distribución geográfica de la formación y apoyo ofrecido por la Secretaría de Educación.|^"