jueves, 18 de diciembre de 2025

Matemáticas


Cálculo básico

PCA. Canarias. DocAp

Concretando el procedimiento de análisis de resultados esbozado en la [entrada precedente], presento en ésta una propuesta de DocAp, compuesto por un gestor, una base de datos (ambos Calc) y un modelo de informe (Writer).


El gestor o soporte es el documento principal, ya que es el que contiene el código del DocAp. Volveremos sobre este soporte para analizar su contenido.

La base de datos es un documento Calc preconfigurado como base de datos, esto es, para contener el listado de los resultados de todas las aplicaciones de la prueba. El objetivo de este documento es recopilar los datos que permitirá desarrollar baremos locales en su momento, y a medio plazo facilitar el análisis de los datos recogidos.

Finalmente, el informe es un documento Writer que se genera automáticamente mediante código y que contiene la información resultante del análisis de cada ejecución individual. En teoría este informe se incorpora al expediente SEO de cada alumno y/o a un directorio de resultados grupales.

Dicho lo anterior, describo ahora el funcionamiento general del DocAp. Después analizaré el código que lo hace posible.

En estos momentos el DocAp está pensado para ser usado por el OE a modo de corrector de la ejecución del alumnado. Supuesta una aplicación grupal (aunque también es posible el uso en evaluación individual), en la que el alumnado emplea el documento que contiene las operaciones y las resuelve como prueba de lápiz y papel, el orientador recoge los materiales e individualmente va trasladando, uno por uno, los datos al soporte.

Se inicia el procedimiento introduciendo los datos de identificación en el formulario de la primera hoja del gestor...


... y se pulsa en el comando RESOLVER OPERACIONES , lo que activa el script encargado de facilitar el acceso al proceso siguiente. El comando BORRAR DATOS, está pensado para facilitar el manejo del DocAp permitiendo la eliminación automática de los datos del alumno anterior.

La segunda fase consiste en la introducción de los resultados (numéricos) de todas las operaciones resueltas por el alumno, lógicamente, en la posición que corresponde al identificador de la operación. Todo esto tiene lugar en la hoja Operaciones, que inicialmente está oculta.


El tercer y último paso consiste en pulsar en el comando FINALIZAR PRUEBA, una vez cumplimentado el conjunto del listado. El resto del procedimiento se desarrolla de forma automática (por medio de código), que reside en el IDE del soporte y cuya estructura de contenidos te muestro en la captura de pantalla siguiente.



El script principal (Main) queda diferenciado del resto para facilitar su localización. Desde él se activa la mayor parte del procedimiento del DocAp, aunque en el módulo auxiliares puedes encontrar algunos script que se asocian a procedimientos complementarios, de funcionamiento independiente, como es el caso del script BorrarDatos, cuya función ya te expliqué en relación al comando del mismo nombre.

Sub Main

Dim oHoja As Object, oCelda As Object
Dim i As Integer
Dim mRespuestas(36) As Variant
Dim mDatos(43) As Variant

'Acceso a la hoja Operaciones
oHoja = ThisComponent.getSheets().getByName("Operaciones")
'Copia de los datos de respuesta
For i = 0 To UBound(mRespuestas())
oCelda = oHoja.getCellRangeByName("D" & i+5)
mRespuestas(i)= oCelda.getString
Next

'Acceso a los datos del alumno
oHoja = ThisComponent.getSheets().getByName("Datos")
'Copia de las respuestas
For i = 0 To UBound(mRespuestas())
oCelda = oHoja.getCellRangeByName("C" & i+7)
oCelda.setString(mRespuestas(i))
Next 
'Paso de datos a matriz de resultados
For i = 0 To 43
oCelda = oHoja.getCellRangeByName("B" & i+1)
mDatos(i) = oCelda.getString
Next

' Acceso a base de datos
AccesoBD(mDatos())

'Creación de informe individualizado
InfoIndiv(mDatos())

'Movimiento a la hoja DatosId (retorno)
vHoja(0,True)
PasoHoja(0)
vHoja(1,False)

End Sub

La función real de este script es gestionar parte importante de los procedimientos fundamentales del DocAp, pero otras partes corren a cargo de script teóricamente secundarios (subrutinas y funciones) pero que son tan importantes como el propio script principal. Es el caso del script que se encarga de trasladar los datos a la base de datos y del conjunto de estructuras que permiten el análisis de los resultados y la composición y posterior escritura del informe individualizado. Ambos subprocedimientos se ubican en sus respectivos módulos y el acceso o llamada a ellos está indicada en negrita en la representación anterior del código de Main.

Además de estas llamadas, Main desarrolla el procedimiento consistente en capturar el listado de puntuaciones que el usuario introduce en Operaciones y trasladarlo a la hoja Datos (también oculta), para después copiar en una matriz (mDatos()) todos los datos relevantes de esta hoja para su traslado como parámetro al código de los script de procesamiento (vg. AccesoBD(mDatos())). En lo fundamental, todas estas manipulaciones de datos se realiza mediante bucles, vg...

'Acceso a los datos del alumno
oHoja = ThisComponent.getSheets().getByName("Datos")
'Copia de las respuestas
For i = 0 To UBound(mRespuestas())
oCelda = oHoja.getCellRangeByName("C" & i+7)
oCelda.setString(mRespuestas(i))
Next 

... lo que ahorra líneas de código y permite que la ejecución sea más eficiente y rápida.

El traslado de los datos a la base de datos se realiza mediante esta subrutina que recibe la matriz que contiene el conjunto de datos como parámetro (Sub AccesoBD(Datos() As Variant))

Sub AccesoBD(Datos() As Variant)

Dim sRuta As String
Dim mArg()
Dim oBD As Object, oHojaBD As Object, oCeldaCampo As Object, oCeldaNuevoRegistro As Object
Dim i As Integer, a As Integer, b As Integer
Dim sEntrada1 As String

'Acceso a los objetos documento (BD_PCA.ods) y Hoja (DatosPrueba)

sRuta = ConvertToUrl("D:/RecursosEvaluacion/Matematicas/CalculoCanariasPCA/BD_PCA.ods")
oBD = StarDesktop.loadComponentFromURL(sRuta, "_blank", 0, mArg())
oHojaBD = oBD.getCurrentController.getActiveSheet()

'Búsqueda del primer registro vacío

For i = 0 To 200
oCeldaCampo = oHojaBD.getCellRangeByName("A" & CStr(i+1))
sEntrada1 = oCeldaCampo.getString()
If sEntrada1 = "" Then
a = i
Exit For
End If
Next

'Escritura de los datos en el registro vacío

For b = 0 To UBound(Datos())
oCeldaNuevoRegistro = oHojaBD.getCellByPosition(b,a)
oCeldaNuevoRegistro.setString(Datos(b))
Next

'Guardar cambios

oBD.store()

'Cerrar BDPruebas.ods

oBD.close(True)

End Sub

Su funcionamiento, ya descrito en una entrada anterior, queda descrito en los comentarios y consiste, en resumen, en acceder al documento  BD_PCA.ods, buscar el primer registro (fila) libre y copiar en él los datos de la matriz-parámetro. Posteriormente se graba el archivo (oBD.store()) y se cierra (oBD.close(True)). Este funcionamiento implica que cada nuevo registro (alumno) se debe volver a repetir todo el procedimiento, pero su ejecución pasa desapercibida para el usuario del DocAP, ya que está totalmente automatizado.

También está automatizado el análisis de los resultados y la escritura del informe, subproceso que corre a cargo del conjunto de script ubicados en el módulo informe

Dada la complejidad de este procedimiento he optado por dividirlo en tres partes: la primera y principal (Sub InfoIndiv(mResultados() As Variant)) es una subrutina que recibe como parámetro los datos resultantes de la aplicación y que llama a dos funciones para procesarlos desde dos perspectivas diferentes y complementarias. Además, esta subrutina tiene como función la composición del texto del informe, la creación del documento y la escritura del contenido.

Sub InfoIndiv(mResultados() As Variant)

'Variables para análisis de datos

Dim mDatPer(5) As String

Dim mPtos(36) As Integer

Dim curso As String

Dim PD As Integer

'Variable para texto de la valoración

Dim PruebaId As String, PruebaDescrip As String

Dim DatosId1 As String, DatosId2 As String

Dim ValorResulta As String,txtInfoCurso As String

Dim ValoraTipOpera As String,txtContenApoyo AS String

'Variables para la creación y la escritura del informe

Dim sRuta As String

Dim mArg()

Dim oNuevoDoc As Object, oTexto As Object

Dim TextoInforme As String

'Pasar datos de la matriz original a las de procesamiento

For i = 0 To 5

mDatPer(i) = mResultados(i) ' Para datos personales

Next

For i = 0 To UBound(mPtos())

mPtos(i) = CInt(mResultados(i+6)) ' Para las puntuaciones de los ítem

Next

PD = CInt(mResultados(43)) ' Para la puntuación total o PD

curso = mResultados(3)    ' Para identificar el curso

'Análisis condicionado al curso sobre la puntuación directa

txtInfoCurso = InfoCurso(curso,PD)

'Análisis condicionado sobre contenidos de los apoyos

txtContenApoyo =  ContenApoyo(curso, mPtos())

'Construcción del contenido del informe

PruebaId = "Prueba de Cálculo Aritmético (PCA). Canarias" & Chr(13) & Chr(13)

DatosId1 = "Centro escolar " & mDatPer(4) & "  " & Chr(13) & "Alumno/a " & mDatPer(0) & " " & mDatPer(1) & " Curso " & curso & Chr(13)

DatosId2 = "Fecha de evaluación " & CStr(mDatPer(5)) & Chr(13) & Chr(13)

PruebaDescrip = "La Prueba de Cálculo Aritmético de Canarias (PCA) tiene como finalidad conocer el nivel competencial de los escolares de Educación Primaria en las cuatro operaciones básicas (suma, resta, multiplicación y división), el empleo de los decimales y de las fracciones. Por ello se puede utilizar para identificar la dificultades específicas de aprendizaje del cálculo en la etapa de E. Primaria." & Chr(13) & "Esta prueba está formada por 37 operaciones. Las 20 primeras son de sumas y restas y se distribuyen entre sumas con una o más cifras, con o sin llevadas, y restas con una o más cifras, con o sin llevadas. Las 17 restantes abarcan operaciones con multiplicaciones de una o dos cifras, con y sin decimales; divisiones por una y dos cifras, con y sin decimales; y finalmente el empleo simple de las fracciones." & Chr(13)

ValorResulta =  mDatPer(0) & " ha resuelto satisfactoriamente " & PD & " operaciones, por lo que, " & txtInfoCurso & Chr(13)

ValoraTipOpera = "Por lo que se refiere a la tipología de las operaciones aritméticas que comprender la PCA, los resultados de " & mDatPer(0) & " merecen las siguientes valoraciones: " & Chr(13) & txtContenApoyo & Chr(13) &  Chr(13) & "En consecuencia, de resultar necesaria algún tipo de intervención de apoyo, esta debería centrarse en las operaciones en las que sus resultados indican cierto grado de dificultad."

TextoInforme = PruebaId & DatosId1 & DatosId2 & Chr(13) & PruebaDescrip & Chr(13) & ValorResulta & Chr(13) & ValoraTipOpera

' Trabajo con el documento de texto y escritura del contenido

sRuta = "private:factory/swriter"

oNuevoDoc = StarDesktop.loadComponentFromURL( sRuta, "_default", 0, mArg())

oTexto = oNuevoDoc.Text

oTexto.insertString(oTexto.getEnd(),TextoInforme, False)

End sub

Los comentarios permiten identificar cada fase del desarrollo del script y en negrita se identifica el acceso a las funciones complementarias que muestro a continuación, empezando por el análisis de categorización...

Function InfoCurso (curso As String, pd As Integer) As String

'Datos condicionantes del análisis (por curso)

Dim i As Integer

Dim mCursos(4) As String

mCursos = Array("P2","P3","P4","P5","P6")

Dim CursoActual As String

Dim min(4) As Integer ' Valor de la puntución mínima

min= Array(3,6,9,12,9)

Dim moda(4) As Integer 'Valor de la moda

moda=Array(17,22,24,25,31)

Dim pc25(4) As Integer ' Valor inferior al pc 25

pc25=Array(13,17,19,22,24)

Dim pc75(4) As Integer 'Valor superior al pc 75

pc75=Array(20,23,26,29,32)

'Variables para construir el texto de respuesta

Dim txtNivelRendimiento As String

Dim txtPropuestaApoyo As String

Dim txtInfo As String

Dim txtInfoFinal As String

'Análisis en función del curso

For i = 0 To 4

CursoActual = mCursos(i)

If CursoActual = curso Then

If pd < min(i) Then

txtNivelRendimiento = "se considera que su nivel de rendimiento es extremadamente bajo."

txtPropuestaApoyo = "En consecuencia se requiere una intervención especializada de apoyo intensivo."

txtInfo = txtNivelRendimiento & " " & txtPropuestaApoyo

Else

If pd <= pc25(i) Then

txtNivelRendimiento = "su nivel de rendimiento se considera inferior al esperado."

txtPropuestaApoyo = "En consecuencia se requiere una intervención específica de apoyo."

txtInfo = txtNivelRendimiento & " " & txtPropuestaApoyo

Else

If pd > pc25(i) and pd < pc75(i) Then

txtNivelRendimiento = "se considera que su nivel de rendimiento se ajusta a lo esperado."

txtInfo = txtNivelRendimiento

Else

If pd >= pc75(i) Then

txtNivelRendimiento = "se considera que sus resultados se sitúan en niveles superiores a los esperados."

txtInfo = txtNivelRendimiento

End If

End If

End If

End If

End If

Next

txtInfo2 = "atendiendo a esos resultados y en función del curso (" & curso & "), " & txtInfo

InfoCurso = txtInfo2

End Function

... cuyo núcleo principal es la estructura de bucle + condicionales anidados que se encuentran a continuación del comentario 'Análisis en función del curso. Obsérvese el uso que se hace en él de la asociación del contenido de las matrices en función de la posición de los datos en términos de curso o nivel. En negrita se identifica lo que devuelve la función a la subrutina que la activa.

De forma similar sucede con la función que analiza los resultados en términos de categorías de operación aritmética...

Function ContenApoyo(curso As String, mPtos() As Integer) As String

Dim txtApoyo AS String

Dim i As Integer, j As Integer

Dim mCatPd(9) As Integer

mCatPd = Array (3,3,4,3,3,4,4,4,5,4)

Dim mResCat(9) As Integer

Dim ContCat(9) As String

Dim OperaTipo(9) As String

Dim mCategorias(36) As String

mcategorias=Array ("A","A","A","C","B","D","D","C","B","B","D","F","C","C","F","E","E","E","F","F","G","G","G","H","H","I","H","G","I","I","I","J","H","I","J","J","J")

'Operaciones de cada categoría

ContCat(0) = "sumas de un dígito sin llevadas (A)"

ContCat(1) = "sumas de dos y tres dígitos sin llevadas (B)"

ContCat(2) = "sumas de uno, dos y tres dígitos con llevadas (C)"

ContCat(3) = "restas de un dígitos sin llevadas (D)"

ContCat(4) = "restas de dos y tres dígitos sin llevadas (E)"

ContCat(5) = "restas de uno a tres dígitos con llevadas (F)"

ContCat(6) = "multiplicaciones por uno y dos dígitos (G)"

ContCat(7) = "divisiones por uno y dos dígitos (H)"

ContCat(8) = "multiplicaciones con decimales (I)"

ContCat(9) = "operaciones con fracciones (J)"

'Sumatorios de resultados por categorías

For i = 0 To UBound(mPtos())

If mcategorias(i) = "A" Then

mResCat(0) = mResCat(0) + mPtos(i)

End If

If mcategorias(i) = "B" Then

mResCat(1) = mResCat(1) + mPtos(i)

End If

If mcategorias(i) = "C" Then

mResCat(2) = mResCat(2) + mPtos(i)

End If

If mcategorias(i) = "D" Then

mResCat(3) = mResCat(3) + mPtos(i)

End If

If mcategorias(i) = "E" Then

mResCat(4) = mResCat(4) + mPtos(i)

End If

If mcategorias(i) = "F" Then

mResCat(5) = mResCat(5) + mPtos(i)

End If

If mcategorias(i) = "G" Then

mResCat(6) = mResCat(6) + mPtos(i)

End If

If mcategorias(i) = "H" Then

mResCat(7) = mResCat(7) + mPtos(i)

End If

If mcategorias(i) = "I" Then

mResCat(8) = mResCat(8) + mPtos(i)

End If

If mcategorias(i) = "J" Then

mResCat(9) = mResCat(9) + mPtos(i)

End If

Next

'Número de categorías a analizar en función del curso

If curso = "P2" Then

j = 4

ElseIf curso = "P3" Then

j = 5

ElseIf curso = "P4" or curso = "P5" Then

j = 6

ElseIf curso = "P6" Then

j = 7

End If

For i = 0 To j

If mResCat(i) =  mCatPd(i) Then

OperaTipo(i) = "* Resuelve satisfactoriamente " & ContCat(i)

ElseIf mResCat(i) =  (mCatPd(i)-1) Then

OperaTipo(i) = "* Podría presentar dificultades para resolver " & ContCat(i)

ElseIf mResCat(i) <=  (mCatPd(i)-2) Then

OperaTipo(i) = "* Presenta importantes dificultades para resolver " & ContCat(i)

End If

txtApoyo = txtApoyo & Chr(13) & OperaTipo(i)

Next

ContenApoyo = txtApoyo

End Function

En este caso, el objetivo es valorar las implicaciones de los resultados organizados en función de la tipología operacional en que se diferencian los distintos reactivos de que consta la prueba. La idea (en este momento) es que, al tratarse de una prueba de tipo screening, cualquier fallo en cualquier ítem (operación) implica un posible nivel de dificultad/riesgo en términos de limitación competencial específica. La ausencia de errores se entiende, en principio, como ausencia de dificultad.

Con esta idea (y sus implicaciones en términos de contenido en el apoyo educativo) como marco de referencia, se implementa también en el análisis la consideración del nivel escolar (curso) en que se sitúa el alumno, ya que los segmentos operatorios o tipo de operaciones que comprende un curso no son los que corresponden a otro, por lo que el enjuiciamiento sólo tiene sentido para aquellos (tipos de operaciones) que correspondan.

Lo que devuelve esta función (en negrita) es simplemente el listado de valoraciones de los bloques de contenido que corresponde emitir en función del curso o nivel del sujeto.

Documentos. Desde [este enlace] tienes acceso a los materiales que componen este DocAp. Es un archivo comprimido que podrás ubicar como carpeta donde desees, aunque deberás modificar la línea de código (sRuta = ConvertToUrl("D:/RecursosEvaluacion/Matematicas/CalculoCanariasPCA/BD_PCA.ods")) que localiza el documento de base de datos (subrutina Sub AccesoBD()).

No hay comentarios:

Publicar un comentario

Comenta esta entrada