domingo, 22 de marzo de 2026

Expedientes

No-Expedientes (I)

Voy a llamar colecciones de archivos a este conjunto de carpetas que contienen archivos (documentos) de alumnos pero que no podemos considerar expedientes SEO. Las razones para ello fueron explicadas (al menos parcialmente) en esta entrada, pero posiblemente sólo en parte. Empezaré por completar esta cuestión.

Cuando un directorio contiene un número muy pequeño de archivos no es posible considerarlo de utilidad para facilitar la información necesaria para el seguimiento del alumno. Eso es lo que sucede obviamente cuando el directorio sólo contiene un archivo y este es el caso de un total de 99 directorios o carpetas inicialmente consideradas parte del conjunto de directorios de nuestra muestra.

Respecto a este amplio grupo de "carpetas" cabe decir que muy posiblemente su existencia no tiene nada que ver con ningún intento deliberado de generar algo parecido a un expediente SEO; posiblemente tan sólo está ahí casualmente o como mero recuerdo de que el ordenador es para el SEO, primero, una compleja máquina de escribir. Al menos así fue en un principio, momento en el que el procesador de texto se convirtió en el principal servicio y la creación de documentos con esa herramienta simplemente el sustituto de la máquina de escribir. Los documentos se imprimian en papel y algunos en vez de perderse quedaban almacenados, facilitando de paso un futuro uso a modo de "modelo-para-el siguiente".

Aunque lo anterior no sea ni del todo cierto ni la única o principal causa del fenómeno que acumulativamente se nos presenta ahora en forma de 99 carpetas con nombres de alumno, lo cierto es que su presencia abultada y peso mucho, distorsionando de forma importante los datos que resultan necesarios para nuestro análisis. Empezando por los estadisticos de centralidad, como la moda, que se ubica precisamente en este grupo, y la media, queda rebajada a un límite extremadamente próximo al mínimo de utilidad para el objetivo pretendido (recuerda, 3,68 archivos por expediente)

El segundo grupo que entraría dentro de este bloque es el formado por las carpetas que contienen dos archivos. Tampoco con dos archivos podemos garantizar un mínimo suficiente para el seguimiento del alumnado, aunque es cierto que en condiciones extraordinarias esa afirmación podría ser puesta en duda.

Podría darse el caso (siempre extraordinario) de que dos archivos condensen la información necesaria para que de su estudio pudiera derivarse información suficiente para el seguimiento del alumno, pero no lo sería con el tipo de documentos que se incluyen en estos expedientes, salvo que lo que deramos decir es que hacemos de la necesidad virtud y nos conformamos con lo que tenemos; pero no es esa la cuestión.

Podemos imaginar un teórico escenario en el que los dos archivos son dos informes psicopedagógicos entre los que han transcurrido algunos cursos (para que puedan aportar información diferenciada y de evolución), o un informe psicopedagógico del inicio de la intervención y un informe de seguimiento que se prolonga satisfactoriamente en el tiempo. Es cierto que en esos casos, idealmente, podríamos hablar de documentación suficiente para facilitar el seguimiento del alumno, pero sólo idealmente.

Puede que en estos extraordinarios casos nos encontráramos en el umbral de lo que es "suficiente", pero más en el plano teórico que en el real: empezando por que un informe psicopedagógico no tiene por objetivo recopilar información de seguimiento del alumno, sino identificar sus necesidades educativas y orientar la intervención, así que no es de esperar que disponer de dos informes (sin más) sea ni suficiente ni satisfactorio. Y de serlo no es posible considerarlo como causa para aceptar las carpetas de dos documentos como expedientes.

El segundo caso (informe + informe+de+seguimiento) es absolutamente extraordinario y es preciso profundizar en el contenido del segundo de esos dos documentos para aceptarlo como expediente. Desde luego no podemos hacerlo sólo por el título de los documentos, así que tampoco en este caso es aceptable como pasaporte para la consideración de expediente SEO.

Y lo que no se puede admitir sin análisis (en general incluso con análisis) como expediente, especialmente si su peso cuantitativo es relevante, debe ser eliminado de la muestra por las mismas razones que lo fueron las carpetas de un documento: para que no distrosiones la muestra. Este es, de nuevo, el caso de las carpetas de dos documentos: son muchas y afectan a la moda y a la media. Como ejemplo: si eliminamos de la muestra las carpetas con un documento, son las carpetas de dos documentos las que determinan la moda de la distribución.

Por último, tenemos las carpetas con tres archivos, el conjunto que mayores dudas suscita precisamente por encontrarse en el límite del mínimo suficiente. En este caso no me atrevo a decir que su descuento pueda ser una medida exenta de dudas, ya que vimos antes que existen casos en los que teóricamente dos archivos podrían constituir ese mínimo. Si añadimos un tercer archivo tenemos, idealmente, ese mínimo suficiente. Lo malo es que sólo en teoría, así que toca analizar carpeta (de tres) por carpeta para comprobar que efectivamente se cumple la condición mínima de dos informes psicopedagógicos + un informe-de-seguimiento. Pueden aceptarse otras combinaciones, pero es necesario un estudio que va más allá de la identificación del documento, cosa que en el momento actual del análisis no nos podemos permitir.

Así que, si bien en este caso partimos de la duda como planteamiento de base y debemos someter a cada una de las carpetas a un análisis de contenido para reubicarlas como expdientes SEO o mantenerlas al margen, inicialmente debemos considerarlas como parte de este bloque de no-suficientes-para-expedientes, ya que tampoco es aceptable su incorporación a la espera de expulsión: es preferible operar al contrario, que es como aquí se ha planteado el procedimiento.

La consecuencia de todo lo dicho hasta este momento es la diferenciación del conjunto muestral inicial en dos bloques: el de las carpetas-no-expdientes y el de los expedientes SEO. El primero está formado por los conjuntos directorio-de-un-archivo + directorio-de-dos-archivos y directorio-de-tres-archivos (pendiente de estudio del contenido). En el segundo estarán todos los directorios que cuentan al menos con cuatro archivos, no por estar garantizado que su contenido es ciertamente el apropiado para el seguimiento, sino porque de la cantidad de documentos de que constan es posible detraer información suficiente para generar datos de utilidad para el seguimiento. Y con eso, al menos inicialmente, nos debe ser suficiente para poder avanzar. Tiempo tendremos de matizar las cuestiones los suficiente para alcanzar consensos mínimos de lo que es una composición y una organización que satisface criterios para hacer de los expedientes SEO herramientas de trabajo útiles.

Y hablando de utilidad, antes de entrar en el análisis que justifica esta entrada, decir que la no pertenencia de determinados conjuntos de carpetas al colectivo expedientes SEO no implica que sus archivos sea irrelevantes para otros análisis. En tiempos en los que la documentación y los datos son un tesoro, ningún archivo es desdeñable. Pero su utilidad no lo es en tanto que expediente, sino en tanto que archivo, por su tipología, por los datos que contiene, por el motivo por el que se creo o por el momento en que se hizo... por la razón que sea, pero como archivo. Ese es otro nivel de análisis, no el que toca aquí y ahora

Empecemos por recordar que en la entrada anterior habíamos creado herramientas basadas en Python que nos permitieron construir un documento csv donde constaban los directorios y el número de archivos que contenía cada uno de ellos. Gracias a esta base de datos nos fue posible observar el peso de cada conjunto de directorios, incluyendo la identificación de aquellos que contenían de 1 a 3 archivos (los que aquí consideramos). Pudimos crear una gráfica de frecuencias (aun no explicamos cómo, ni todavía toca), la cual nos permitió visulizar el peso de las carpetas con menos archivos en nuestra muestra, con las consecuencias que antes expliqué: no podemos permitir que ese gran peso de las carpetas-no-expedientes distorsionen el análisis que nos planeamos realizar respecto al potencial de lo que denominamos expedientes SEO si es que queremos convertirlos realmente en una herramienta de trabajo.

Mediante el simple acceso al archivo csv desde LO-Calc ha sido posible dividir la base de datos original en dos bases de datos, la primera con las carpetas de las que ahora nos ocupamos, la segunda con los que consideramos expedientes SEO. Convertimos la primera en documento Calc y trabajamos esos datos para obtener la información cuantitativa básica que te muestro a continuación.

Gráfico y tabla describen la misma realidad en lo que a "carpetas" se refiere: el grupo de un archivo representa cerca de la mitad del total de carpetas y el de dos archivos cerca de un tercio del total; pero si lo analizamos en términos de archivos, se invierten los pesos. De momento nos vamos a centrar en el peso de las carpetas, ya que estamos hablando de "expedientes", no de su contenido.

Pero estos datos poco más nos pueden aportar, y nada de ello es relevante para el segundo objetivo de este primer análisis: identificar el contenido para conocer sus características y, en el caso de las carpetas con 3 archivos, ver cuales de ellas podrían ser consideradas expedientes SEO

Para ello necesitamos algo más que acceso a una base de datos csv, necesitamos acceso a las carpetas físicas para generar agrupaciones en función del número de archivos de que constan para poder listarlos de forma diferenciada. No nos salimos (aun) de los límites de los archivos como fuente de datos, pero tenemos que avanzar en esa línea si queremos conocer las características específicas de esos no-expedientes o aun-no-expdedientes. Y eso no es algo que podamos hacer mediante OOo Basic. Sí mediante Python



#Librerías necesarias ----------------------------------------------------------

from pathlib import Path
import shutil

#Función -------------------------------------------------------------------------

def procesar_directorios(ruta,archivos,directorio):

    base_path = Path(ruta)
    destino_path = base_path / directorio

    if not base_path.is_dir():	    # Validar que la ruta existe
        print(f"Error: La ruta {ruta} no es un directorio válido.")
        return

    if not destino_path.exists():	  # Crear directorio de destino si no existe
        destino_path.mkdir(parents=True)

# Analizar contenido del directorio

    for item in base_path.iterdir():
        if item.is_dir() and item.name != directorio:   # Solo procesamos carpetas y evitamos la propia carpeta de destino
            # Conteo en profundidad (recursivo). f.is_file() asegura que solo contamos archivos
            conteo = sum(1 for f in item.rglob('*') if f.is_file())
            if conteo == archivos:	  # Criterio de traslado
                print(f"Moviendo '{item.name}' ({conteo} archivos)...")
                try:
                    shutil.move(str(item), str(destino_path / item.name)) # Se mueve la carpeta completa con todo su contenido
                except Exception as e:
                    print(f"No se pudo mover {item.name}: {e}")

#Ejecución de la función------------------------------------------------------------

if __name__ == "__main__":

#Primero introduce los datos necesarios
    # 1. Introduce aquí la ruta completa de la carpeta a analizar
    ruta_origen = r'Aquí_Tu_ruta' 
    # 2. Número de archivos para que una carpeta sea movida
    num_archivos =  #Aquí_número_archivos
    # 3. Nombre de la carpeta donde se trasladarán los resultados
    destino = 'Aquí_Nombre_directorio_para_carpetas'

#Despues llama a la función
    procesar_directorios(ruta_origen,num_archivos,destino)

    print("Proceso completado.")


Mediante este script obtenemos los "expedientes" que contienen un determinado número de archivos. Por ejemplo, las carpetas con uno, dos o tres archivos (con independencia de que existan subdirectorios internos) y los trasladamos íntegramente a un directorio de destino, específico para ese grupo de "expedientes". La isntrucción if conteo == archivos: es fundamental para ello.

Debes tener en cuenta que los directorios de destino se crean en el mismo directorio donde se buscan las carpetas-expedientes, así que debes poner nombres de directoriosq que resulten fáciles de identificar y que expliciten el contenido, por ejemplo Dir_2_archivos.

Gracias a este script podemos disponer de diferentes directorios donde se guardan los no-expedientes (y los expedientes), diferenciándolos por le criterio número-de-archivos. Concretamente he creado cuatro (sub)directorios para los no-expedientes (uno, dos u tres archivos) y un (sub)directorio para los expedientes (4 y más archivos). De este modo me puedo centrar en el análisis de cada uno de los conjuntos de datos.

Empezando por el subconjunto no-expedientes de un archivo, me interesa obtener un listado de todos los archivos que contiene (no de los directorios, que ya está disponible) para conocer detalles relevantes de los mismos que puedan servir para realizar análisis pertinentes de los subconjuntos restantes, además de para conocer las características de los de este subconjunto.

Para obtener este listado ejecutaré el siguiente script:

 

#Librería -------------------------------------------------------------

from pathlib import Path

#Función ---------------------------------------------------------------

def listar_y_guardar_archivos(ruta_base, nombre_txt):
    """
    Lista archivos de forma recursiva, los muestra por pantalla y los guarda
    en el subdirectorio 'documentos' ya existente en la raíz del script.
    """
    # Definición de rutas según estructura solicitada
    directorio_script = Path(__file__).parent
    ruta_txt_salida = directorio_script / "documentos" / nombre_txt
    directorio_explorar = Path(ruta_base)

    # Validación de la ruta de origen
    if not directorio_explorar.exists() or not directorio_explorar.is_dir():
        print(f"Error: La ruta '{ruta_base}' no es válida.")
        return

    # Obtención de archivos en profundidad
    archivos = [archivo for archivo in directorio_explorar.rglob("*") if archivo.is_file()]

    if archivos:
        # Escritura en el archivo .txt dentro de /documentos/
        with open(ruta_txt_salida, "w", encoding="utf-8") as f:
            for a in archivos:
                nombre_solo = a.name
                print(nombre_solo)          # Mostrar solo nombre por pantalla
                f.write(nombre_solo + "\n") # Guardar solo nombre en el archivo
    else:
        print("No se encontraron archivos.")

#Script de llamada a la función -------------------------------------------------------------------------

if __name__ == "__main__":
    # Variables locales pasadas como parámetros
    ruta_a_explorar = "Aqui_Tu_Ruta"
    archivo_reporte = "Mi_Lista.txt"
    
    listar_y_guardar_archivos(ruta_a_explorar, archivo_reporte)


Gracias a este script podemos crear los listados de archivos (únicamente de archivos) que deseemos en función del directorio raiz (ruta) en que se encuentren los no-expedientes o los expedientes (o cualquier otra configuración de archivos). Esta lista se exporta como documento .txt y queda disponoble para un posterior manejo mediante procedimiento de acceso a documentos de datos no estructurados, aunque el formato de organización del contendio (como lista simple) facilita el acceso y el recorrido del citado .txt, lo que no evita que necesitemos recurrir a procedimientos específicos de acceso a este tipo de archivos, como es el caso.

Con fines didácticos más que por necesidad voy a proceder ahora como si de dos fases diferenciadas dentro del análisis se tratara y generaré un script para acceder al contenido del archivo-lista recien creado para ejecutar sobre ella un procedimiento simple de análisis que consiste en estudiar los tipos de archivos a fin de responder a una cuestión que ha estado en la base del análisis planteado hasta el momento respecto al colectivo documental de no-expdientes de un elemento: la ausencia de interés por generar un expediente SEO como motivación para la creación de estas carpetas.

En sentido estricto es esta una suposición difícil de comprobar ya que implica un conocimiento de intenciones del que no podemos disponer, pero sí podemos estudiarlo de forma indirecta en el siguiente supuesto (que ya se expuso en otro momento): son documentos que reflejan fundamentalmente el uso del medio informático como mero procesador-de-texto o máquina-de-escribir. De ser esto cierto, los documentos deben tener extensiones propias de estos servicios y la presencia de extensiones propias de servicios que implican cierto interés por el almacenamiento en formato pdf y más aun por documentos basados en hojas de cálculo deben estar ausentes o mínimamente representados. Veamos hasta qué punto se cumple esta hipótesis en el bloque de documentos en que con más facilidad y razón de ser se pruee cumplir.

Para ello crearemos un script que accede al listado, lo carga en memoria, analiza en cada línea (entrada o registro) la extensión del documento y realiza un recuento de tipología, lo expresa mediante una tabla simple y genera una gráfica de barras con esos datos.




#Bibliotecas ----------------------------------------------------------------------------------

import pandas as pd
import matplotlib.pyplot as plt
import os

#Función ---------------------------------------------------------------------------------------

def analizar_extensiones_txt(ruta_archivo):

# 1. Validación de existencia
    if not os.path.exists(ruta_archivo):
        print(f"⚠️ Error: No se localizó el archivo en: {ruta_archivo}")
        return pd.DataFrame(), None

    try:
        with open(ruta_archivo, 'r', encoding='utf-8') as f:
            lineas = f.read().splitlines()
        
# 2. Extraer extensiones
        extensiones = [os.path.splitext(doc.strip())[1].lower() or 'Sin extensión' 
                       for doc in lineas if doc.strip()]

        if not extensiones:
            print("pst... El archivo está vacío.")
            return pd.DataFrame(), None

# 3. Crear Tabla de Datos
        df = pd.DataFrame(extensiones, columns=['Extensión'])
        tabla_frecuencia = df['Extensión'].value_counts().reset_index()
        tabla_frecuencia.columns = ['Extensión', 'Frecuencia']

# 4. Configurar el gráfico (sin mostrarlo)
        fig, ax = plt.subplots(figsize=(10, 6))
        ax.bar(tabla_frecuencia['Extensión'], tabla_frecuencia['Frecuencia'], color='teal')
        ax.set_title('Análisis de Extensiones')
        ax.set_ylabel('Cantidad')
        
        return tabla_frecuencia, fig

    except Exception as e:
        print(f"Ocurrió un error inesperado: {e}")
        return pd.DataFrame(), None

# --- Script ----------------------------------------------------------------------------------------------------------------

mi_ruta_archivo = r"C:/Users/alons/proyectos_python/proyecto_expedientes/documentos/listado_uno.txt"

# Ejecución con validación
resultado_tabla, grafico = analizar_extensiones_txt(mi_ruta_archivo)

if not resultado_tabla.empty:
    print("### TABLA DE RESULTADOS ###")
    print(resultado_tabla)
    if grafico:
        plt.show()
else:
    print("No se pudieron generar resultados. Revisa la ruta o el contenido del archivo.")


Este gráfico muestra la distribución de la tipología de archivos. Predominan claramente los archivos .doc, creados con el procesador de textos Word. Además tienen cierta antigüedad, ya que las versiones actuales de Word tienen .docx por extensión. Este dato confirma nuestra hipótesis, que se ve reforzada por el sumatorio que resulta de añadir a ese grupo los documentos de las extensiones .docx (3 archivos) y .odt (5 archivos); esto hace un total de 90 archivos, el 90,9% del total.

Tipo de archivos Número Porcentaje
Documento de texto 90 90,9%
PDF 5 5%
Hoja de cálculo 4 4%
Esta tabla recoge ese sumatorio y facilita la observación de que el resto (9 archivos) se dividen casi a partes iguales entre .pdf (5 archivos) y otros 4 sobre hojas de cálculo. Estos 9 archivos (el 9,1% del total) podemos considerarlos como contrarios a la hipótesis inicial, lo que no impide que ésta se confirme, pero la matiza: el 9% de los no-expedientes de un archivo se pueden considerar expedientes fallidos, aunque el 90% encaja perfectamente con la interpretación desarrollada respecto a considerar los 99 directorios que constan de un único archivo como mera supervivencia de las formas iniciales de uso de los medios informáticos por parte de los SEO, que generaban y mantenian expdientes SEO analógicos, aunque se servían de los medios informáticos a modo de "máquina de escribir", sin más pretensión.

Finalizo aquí esta primera parte del análisis de los no-expedientes, en la que me he centrado en el estudio del primer subconjunto de este bloque. Para su desarrollo he empleado funciones de LO-Calc, aunque predominaron los script basados en Python

En una próxima entrada trabajaré con los directorios de dos archivos, ya que interesa observar en ese grupo el peso de determinadas configuraciones de archivos en relación a la distinción observada en este primer bloque (entre no-expedientes y expedientes fallidos), pero también para apreciar la incidencia de un tipo concreto de archivos (documentos): los informes psicopedagógicos.