Mostrando entradas con la etiqueta Aplicación. Mostrar todas las entradas
Mostrando entradas con la etiqueta Aplicación. Mostrar todas las entradas

martes, 23 de diciembre de 2025

Evaluación

Automatización de la evaluación

Input incremental (II)




Dado que en la [entrada anterior] establecimos previamente los diferentes soportes de interfaz para la fase input, en esta daremos un paso más y crearemos esa interfaz a partir de los datos de una matriz y en función de la edad. En este caso es así dadas las características de la prueba de referencia (PLON-R. Fonología).

No se trata de un procedimiento totalmente automatizado, ya que la hoja sobre la que crearemos la interfaz y parte de los elementos que contiene han tenido que ser creada previamente, pero lo que ahora nos interesa es la parte nuclear de su contenido: el listado de palabras que deberá producir el alumno y que deberemos evaluar nosotros.

Este modo de resolver la cuestión nos ahorra crear tantas hojas/interfaces como grupos input existan en la prueba. Así en PLON-R. Fonología resolvemos con una lo que según el procedimiento anterior precisaba cuatro. Se eliminan también unos cuantos script asociados al manejo de esas hojas.

Sub CrearLista

Dim oHoja As Object, oCelda As Object
Dim listado() As String

Dim annos As String
Dim edad As Integer

annos = al_edad()
edad = CInt(annos)

If edad > 6 Then
edad = 6
End If

listado() = copiaPal(edad)

'Acceso a la página

oHoja = ThisComponent.getSheets().getByName("ListaPal")

oCelda = oHoja.getCellRangeByName("B2")
oCelda.setString("Palabras")
oCelda = oHoja.getCellRangeByName("C2")
oCelda.setString("Puntos")

For i = 0 To UBound(listado())
oCelda = oHoja.getCellRangeByName("B" & i+3)
oCelda.setString(listado(i))
Next

End Sub

Pasemos ahora a analizar cómo se desarrolla esta propuesta. El primer paso consiste en acceder a la edad del sujeto, ya que ésta es la que determinará el desarrollo del resto. Para ello, desde nuestro script principal, haremos uso de la función, creada en versiones anteriores, que nos permitía acceder a ese datos (annos = al_edad()). 

Function al_edad () As string

Dim oHoja As Object, oCelda As Object
Dim i As Integer
Dim edad As String

'Acceso a Resultados para capturar la edad
oHoja = ThisComponent.getSheets().getByName("Resultados")
oCelda = oHoja.getCellRangeByName("B4")
edad = oCelda.getString

al_edad = edad

End Function

Una vez que disponemos de ese dato (string) lo convertimos a integer (edad = CInt(annos)) para operar con él (If edad > 6 Then -> edad = 6 -> End If), evitando posibles errores en el manejo de los datos de edad cuando ésta supera los 6 años.

El paso siguiente consiste en acceder a la función que nos da acceso al contenido con el que trabajar (listado() = copiaPal(edad)): el listado de palabras que corresponde por edad y que deberemos recuperar de la hoja Matrices.

Function CopiaPal(al_edad As Integer)

'para acceso a objetos
Dim oHoja As Object, oCelda As Object
Dim listaPal () As String

'Para acceso a datos
Dim i As Integer
Dim max As Integer
Dim edades() As Integer
Dim ptos_max() AS Integer

edades = Array(3,4,5,6)
ptos_max = Array(21,44,56,61)

'Calculo y establecimiento del límite superior del listado

For i = 0 To UBound(edades())
If edades(i) = al_edad Then
max = ptos_max(i)
End If
Next 

ReDim listaPal(max-1)

'Acceso a la hoja que contiene la base de datos

oHoja = ThisComponent.getSheets().getByName("Matrices")

For i = 0 To UBound(listaPal())
oCelda = oHoja.getCellRangeByName("I" & i+1)
listaPal(i) = oCelda.getString()
Next

CopiaPal = listaPal()

End Function

Esta función accede al contenido de la hoja Matrices y accede al valor numérico de la extensión del listado que debe crear haciendo uso del parámetro al_edad que le hemos pasado desde el script principal, mediante una analogía entre los valores de posición de la matriz edades y los de la matroz ptos_max.

For i = 0 To UBound(edades())
If edades(i) = al_edad Then
max = ptos_max(i)
End If
Next 

Con ese dato de longitud o límite superior redimensionamos la matriz que contendrá el listado de palabras (ReDim listaPal(max-1)). Mediante un segundo bucle recorremos la columna I y accedemos a las palabras que incluimos como elementos de la matriz (listaPal(i) = oCelda.getString()) que la función devolverá al script principal (CopiaPal = listaPal()).

De regreso a éste, sólo nos queda posicionarnos en la hoja sobre la que escribir los títulos de las columnas...

oCelda = oHoja.getCellRangeByName("B2")
oCelda.setString("Palabras")

... y el listado y proceder a ello mediante el procedimiento ya conocido de asignar contenido a las celdas.

For i = 0 To UBound(listado())
oCelda = oHoja.getCellRangeByName("B" & i+3)
oCelda.setString(listado(i))
Next

Si deseáramos completar el procedimiento y dejar listo los materiales para un uso posterior deberíamos implementar código que capture el resultado de la aplicación del test (puntuación de cada ítem) para trasladarlos a la hoja Resultados, eliminando antes el contenido de la lista de palabras y de la puntuación.

A parte de este posible desarrollo del script, también nos podemos plantear otros que implican establecer un condicionamiento múltiple. Un ejemplo sobre PLON-R. Fonología podría ser seleccionar únicamente los fonemas y no los grupos fonémicos, o sólo los fonemas oclusivos, o sólo los fonemas sonoros... Los ejemplos son múltiples, tantos como variables diferenciadoras hayamos establecido. Además esas subcategorizaciones podemos establecerlas secuencialmente o mediante condicionales anidados. En cualquier caso, lo interesante es que podemos hacer uso del procedimiento básico que hemos explicado en esta entrada para automatizar la selección del contenido sobre el que trabajar en función de los criterios que nos interese aplicar en cada caso.  

lunes, 22 de diciembre de 2025

Evaluación


Automatización de la evaluación

Input incremental (I)



La prueba PLON-R. Fonología es un buen ejemplo (y motivo) para que nos planteemos cómo resolver la presentación de los reactivos cuando ésta requiere (en este caso por procedimiento estandarizado) un ajuste en función de la edad del niño. Aquí el inicio es común a todas las edades, pero la finalización está en función de la edad, es variable en número de reactivos e incremental.

Es posible abordar la automatización de la presentación de este tipo de pruebas desde diferentes enfoque, unos más complejos, otros más simples, aunque a veces la simplicidad resulta serlo menso de lo que parece.

Empecemos por una posible solución, que se concreta como distintas opciones de presentación, adaptadas a priori a las exigencias de cada edad: una pantalla para tres años, otra para cuatro y así hasta la pantalla de seis años, que es la edad máxima. En total disponemos de cuatro posibilidades y sólo mostraremos aquella que se ajuste al contenido de la variable condicionante (la edad).

En OOo Basic esta es la forma en que se concreta el procedimiento que lo hace posible, empezando por el código de acceso a la pantalla (hoja) de cada edad, inicialmente oculta:

Sub IrCuestionario

'Variables

Dim oHoja As Object, oCelda As Object

Dim Edad As String

Dim al_edad As Integer

'Acceso al valor de edad

oHoja = ThisComponent.getSheets().getByName("Resultados")

oCelda = oHoja.getCellRangeByName("B4")

Edad = oCelda.GetString()

al_edad = CInt(Edad)

'Acceso al cuestionario en función de la edad

If al_edad = 3 Then

vHoja(1,True)

PasoHoja (2)

ElseIf al_edad = 4 Then

vHoja(2,True)

PasoHoja (3)

ElseIf al_edad = 5 Then

vHoja(3,True)

PasoHoja (4)

ElseIf al_edad >= 6 Then

vHoja(4,True)

PasoHoja (5)

End If

vHoja(0,False)

End Sub

Primero accedemos a la celda que contiene el dato de edad (Edad = oCelda.GetString()) y después visibilizamos esa hoja (vHoja(1,True)) mediante un condicional (If al_edad = 3 Then) y nos posicionamos en ella (PasoHoja (2)), a la vez que ocultamos la hoja de procedencia (vHoja(0,False)) para que sólo quede visible la pantalla que nos interesa.

Después de resuelta esta primera fase, y dado que el diseño del DocAp lo define como instrumento para que el OE registre los resultados, corresponde ahora copiarlos en su ubicación "definitiva" y borrar los datos introducidos para que no interfieran con un uso futuro. Además deberemos devolver el protagonismo a la hoja de inicio y ocultar la que acabamos de emplear.

De todo ello se encargan los siguientes script:

Sub Puntuar_3a

Dim elem As Integer
Dim edad As String

'Elementos en función de la edad
elem = 20
'Llamada a función de captura de edad
edad =  al_edad()
'Llamar a la subrutina Puntuar()
Puntuar(elem,edad)

End Sub

Function al_edad () As string

Dim oHoja As Object, oCelda As Object
Dim i As Integer
Dim edad As String

'Acceso a Resultados para capturar la edad
oHoja = ThisComponent.getSheets().getByName("Resultados")
oCelda = oHoja.getCellRangeByName("B4")
edad = oCelda.getString

al_edad = edad

End Function


Sub Puntuar (n_i As Integer, edad As String)

Dim oHoja As Object, oCelda As Object

Dim i As Integer, edad_n As Integer, nh As Integer

Dim mDatos(n_i) As Integer

'Canalización hacia la página de registro en función de la edad

edad_n = CInt(edad)

If edad_n < 6 Then

oHoja = ThisComponent.getSheets().getByName("Lista" & edad & "a")

ElseIf edad_n >= 6 Then

oHoja = ThisComponent.getSheets().getByName("Lista6a")

End If

'Paso de datos a matriz de resultados

For i = 0 To UBound(mDatos())

oCelda = oHoja.getCellRangeByName("E" & i+4)

mDatos(i) = oCelda.getValue

Next

'Copia de los datos a la hoja Resultados

oHoja = ThisComponent.getSheets().getByName("Resultados")

'Copia de los datos en la hoja

For i = 0 To UBound(mDatos())

oCelda = oHoja.getCellRangeByName("B" & i+6)

oCelda.setValue(mDatos(i))

Next

'Identificar la hoja de datos a ocultar

If edad_n = 3 Then

nh = 1

ElseIf edad_n = 4 Then

nh = 2

ElseIf edad_n = 5 Then

nh = 3

ElseIf edad_n >= 6 Then

nh = 4

End If

'Movimiento a la hoja DatosId

vHoja(0,True)

PasoHoja(0)

vHoja(nh,False) 'Oculta la hoja de datos que corresponde según la edad del sujeto

'Llamar a la subrutina para borrar los datos del cuestionario de puntuación

BorrarPtos(edad_n)

End Sub

El script principal (Puntuar_3a) se repite tantas veces como periodos etarios tiene el test (cuatro) y aparentemente, como puedes ver, es muy simple: en realidad se limita a entregar un dato (elem = 20) y a solicitar otro a una función (edad =  al_edad()), para entregar ambos como parámetros a una subrutina (Puntuar(elem,edad)), que es la que se encarga de la mayor parte del trabajo. Esto es así porque la subrutina es, en realidad, la abstracción de lo que podría contener el script principal si fuera único, si sólo hubiera un bloque de edad y no cuatro.

Mientras que la función al_edad() es muy simple (se limita a acceder a la celda que contiene la edad del alumno para entregársela al script), la subrutina es compleja:

  • Se sitúa en la página empleada para recoger los datos
  • Captura esos datos
  • Accede a la página de almacenamiento de datos y los copia
  • Visualiza la hoja principal y desplaza el foco hacia ella
  • Identifica la hoja de registro que se debe ocultar
  • La oculta esa hoja de registro
  • Llama a la subrutina de borrado del contenido de la hoja de registro
Esta nueva subrutina de borrado recibe como parámetro el dato de la edad del sujeto, ya que lo necesita para identificar qué hoja debe borrar y cuantas celdas debe recorrer.

Sub BorrarPtos(edad As Integer)

Dim oHoja As Object, oCelda As Object

Dim i As Integer, n As Integer

Dim IdPag As String

'Ir a la página

If edad = 3 Then

IdPag = "Lista3a"

n = 20

ElseIf edad = 4 Then

IdPag = "Lista4a"

n = 43

ElseIf edad = 5 Then

IdPag = "Lista5a"

n = 55

ElseIf edad >= 6 Then

IdPag = "Lista6a"

n = 60

End If

'Nos posicionamos en la hoja y recorremos las celdas para borrar el contenido

oHoja = ThisComponent.getSheets().getByName(Idpag)

For i = 0 To n

oCelda = oHoja.getCellRangeByName("E" & i+4)

oCelda.setString("")

Next

End Sub

Se selecciona la hoja sobre la que actual mediante una estructura condicional y borrar su contenido mediante un bucle que lo recorre. El límite superior de ese recorrido viene definido también por la edad del sujeto, ya que es esta la que determina el número de reactivos que se aplican y, por tanto, de posibles celdas en las que se recoge la puntuación.

Evaluación

Automatización de la evaluación

Input de contenido variable




Por diferentes motivos, es frecuente que la presentación del input se vea constreñida por las condiciones de estandarización de la prueba, a lo que se añade, en cuanto a su automatización, las limitaciones que imponen los derechos de autor. En todos esos muy frecuentes casos la única solución es, simplemente, limitarse a lo que nos viene dado y renunciar a cualquier propósito de automatización. Como mucho, y para nuestro propio consumo, podemos sustituir la presentación del material visual en formato papel por el formato digital, después de comprobar que no afecta a los criterios de normalización.

Una vez que hemos superado esa parte, también por diversas causa y con diferentes objetivos, estamos libres de reformular, recapitular, reutilizar (y reinterpretar)... los materiales y los procedimientos, siempre, claro está, que informemos convenientemente del qué y del para qué de nuestras propuestas y de su significado. 

Evidentemente esas limitaciones y todo lo que implican no afectan a determinadas pruebas, incluyendo las que nosotros mismos creemos. No se ven afectadas porque somos nosotros los que definimos de esa forma su estandarización: incluyendo en ella la automatización de la presentación del input.

Para las circunstancias que expongo en estos dos anteriores párrafos sirve lo que viene a continuación, que surge de la necesidad de abordar el trabajo con dos pruebas que, por diferentes motivos, presentan un input de contenido variable en función del cumplimiento de determinadas condiciones: en estos dos casos y respectivamente, la condición es la edad y el curso. Y las pruebas son el test PLON-R. Fonología y el test PCA. Canarias.

En lo que se refiere al PLON-R Fonología, el criterio de referencia es la edad y la presentación del input se ve incrementado acumulativamente en función de esta de forma variable e irregular: a los niños de tres años (edad de inicio de la prueba) se les aplican x ítem y a los de cuatro los anteriores más los suyos propios. No hay, por lo tanto, condición de inicio, pero sí de final. Y hay, en consecuencia, una PD total variable en función del número de ítem aplicados, a su vez, en función de la edad del sujeto.

En el caso de PCA el procedimiento es más simple, pero a la vez más complejo en términos de análisis, por no estar del todo claramente definido en términos de estandarización. Se supone que hay un cuestionario con un número total de ítem que se dividen entre ítem para el primer ciclo de E. Primaria, pero que después resulta reducido a su segundo curso, (y más) pero que, además la aplicación real de la prueba no se limita a ese subconjunto de ítem, usándose también el segundo subconjunto (teóricamente pensado para los cursos superiores a P2), los cuales contienen un segundo y mucho más complejo conjunto de operaciones que se presentan de forma mucho menos diferenciada que las del primer bloque.

Estas complejidades se resuelven después en la práctica de forma muy simple: se aplica toda la prueba a todos los cursos y se establece un límite de tiempo para la ejecución (30 minutos). El "problema" es que se presentan a niños pequeños operaciones que no conocen en absoluto y a los mayores operaciones que no dominan aun junto con otras que son muy sencillas para su nivel de aprendizaje. Y como lo que no va en lágrimas, va en suspiros, la simplicidad de la presentación se torna en complejidad en el análisis. Complejidad, eso sí, en potencia, que no de hecho, ya que también en esto se resuelve sencillamente el problema: nos limitamos a posicionar al sujeto en términos de percentil en función de su PD y curso.

Creo haber dado indicios suficientes de por donde van los problemas a los que nos enfrentamos en un planteamiento de automatización del input en ambas pruebas (una vez cumplidos los requisitos de sus respectivas condiciones de aplicación estandarizada), cuando buscamos usarlas en una segunda fase de aplicación orientada a objetivos específicos (reformulación del objetivo y/o reanálisis de los resultados). Se podría añadir, además, una tercera complejidad, perfectamente pensable y útil en ambos casos (más aun en PCA): la adaptación del contenido de la prueba a las características o niveles competenciales del sujeto.

Además te habrás percatado de que lo que aquí se ha expuesto no se limita a estas dos pruebas, ya que, con algunas variaciones, es compartido, en realidad, por otras muchas pruebas, por lo que su solución (o soluciones, que no hay una única) lo es también de esas otras muchas, posiblemente, eso sí, con alguna adaptación.

Pero vayamos por parte, que son varias las cuestiones que ahora tenemos encima de la mesa y conviene afrontarlas por partes; cada una de esas partes en una entrada podría ser un buen planteamiento.