Curso Descartes JS
Sesión 8

Tabla de contenido

Variables y funciones

Introducción

DescartesJS cuenta con muchas funciones y variables propias que evitan que el usuario tenga que programar las acciones más básicas. Es difícil tener en mente todas estas funciones y variables, por lo que se espera que este último capítulo funcione como una guía de rápido acceso a las funciones y variables intrínsecas de DescartesJS.

También se incluyen, cuando se considera importante, algunos ejercicios que agrupan el uso de algunas de estas funciones y variables.

Variables intrínsecas de DescartesJS

DescartesJS tiene muchas variables asociadas a propiedades de los espacios, a acciones del ratón, a estatus de controles gráficos, etcétera. Estas variables pueden usarse tanto para conocer el estado de ciertas partes de un objeto interactivo (por ejemplo, el tamaño de un espacio), así como para modificar propiedades mismas del interactivo. A continuación se enuncian, en distintos apartados, dependiendo de la acción o la funcionalidad a la que pertenecen.

Variables de Espacio

Las variables de espacio permiten conocer el alto, ancho y escala de un espacio. Adicionalmente, el usuario puede modificarlas para lograr espacios de características particulares. Las variables de espacio empiezan siempre con un prefijo que es el identificador del espacio en cuestión. Como notación usamos <Nombre del espacio>, para indicar que ahí va el identificador del espacio.

<Nombre del espacio>._w: Esta variable permite conocer el ancho de un espacio en pixeles. El sufijo w viene de width, que es anchura. Por ejemplo, la variable Esp._w nos permitiría conocer cuántos pixeles tiene de ancho el espacio Esp.

<Nombre del espacio>._h: Esta variable permite conocer el alto de un espacio en pixeles. El sufijo h viene de height, que es altura. Por ejemplo, la variable Esp._h nos permitiría conocer cuántos pixeles de altura tiene el espacio Esp.

<Nombre del espacio>.Ox: Esta variable permite conocer el desplazamiento horizontal del origen en pixeles. El sufijo Ox viene de offset de x. Por defecto, el origen del plano aparece en el centro del espacio. Pero se le puede asignar un desplazamiento (u offset) positivo si se desea moverlo a la derecha, o negativo si se quiere moverlo a la izquierda.

Esta variable sirve para conocer tanto el desplazamiento horizontal del origen, pero también se le puede asignar un valor si se quiere dar un desplazamiento horizontal. Es análoga a la variable que aparece como el campo de texto O.x en el selector Espacios cuando se tiene seleccionado el espacio en cuestión.

<Nombre del espacio>.Oy: Esta variable permite conocer el desplazamiento vertical del origen en pixeles. El sufijo Oy viene de offset de y. Por defecto, el origen del plano aparece en el centro del espacio. Pero se le puede asignar un desplazamiento (u offset) negativo si se desea moverlo hacia arriba, o positivo si se quiere moverlo hacia abajo.

Esta variable sirve para conocer tanto el desplazamiento horizontal del origen, pero también se le puede asignar un valor si se quiere dar un desplazamiento horizontal. Es análoga a la variable que aparece

como el campo de texto O.y en el selector Espacios cuando se tiene seleccionado el espacio en cuestión.

<Nombre del espacio>.escala: Esta variable se usa para conocer la escala (el número de pixeles que hay entre una unidad y otra) del espacio. Por ejemplo, E7.escala es la variable asociada a la escala del espacio E7. También es posible asignarle un valor a dicha variable para forzar una escala especifica al espacio. Es análoga a la variable que aparece como el campo de texto escala en el selector Espacios cuando se tiene seleccionado el espacio en cuestión.

En el siguiente objeto interactivo puedes verificar algunas de estas variables:

Observa la configuración del control numérico, para la variable E2.escala. Los otros dos controles son análogos.

<Nombre del espacio>.rot.y: Esta variable sólo es válida para espacios tridimensionales. Guarda la rotación del espacio en grados alrededor del eje $y$. Por ejemplo, E2.rot.y sería la variable que guarda la rotación en grados alrededor del eje $y$ del espacio tridimensional E2.

<Nombre del espacio>.rot.z: Esta variable sólo es válida para espacios tridimensionales. Guarda la rotación del espacio en grados alrededor del eje $z$. Por ejemplo, E2.rot.z sería la variable que guarda la rotación en grados alrededor del eje $z$ del espacio tridimensional E2.

Es posible asignarle un valor a las dos variables anteriores, para forzar que el espacio al inicio tenga la perspectiva deseada. En el siguiente objeto interactivo puedes verificar el uso de las variables de espacio tridimensional:

Interactúa con el objeto y observa que puedes rotarlo o cambiar su escala, tanto de los controles como con los botones del ratón. Para algunos objetos interactivos de aprendizaje conviene, en ocasiones, fijar el espacio y dejar que las rotaciones se puedan hacer sólo desde los controles.

Variables del ratón

Las variables del mouse o ratón se usan para identificar el estado de este dispositivo; por ejemplo, si el botón izquierdo ha sido oprimido, o si está siendo oprimido. También se pueden conocer las coordenadas relativas del ratón. Para usar estas variables es preciso indicar el espacio relacionado (sobre el cual se quiere conocer el estado del ratón) mediante un prefijo, que es el identificador del espacio. Como notación usamos <Nombre del espacio> para indicar que ahí va el identificador del espacio.

<Nombre del espacio>.mouse_x: Esta variable permite conocer la coordenada horizontal relativa al plano cartesiano en que el mouse se encuentra al momento de estar presionado su botón. Su valor se refresca sólo cuando el mouse está oprimido (si el mouse sólo se pasea sin estar oprimido, el valor de esta variable no se refresca). Por ejemplo, la variable Esp.mouse_x nos indica la coordenada horizontal del mouse en el espacio Esp cuando se hace clic con el mismo.

<Nombre del espacio>.mouse_y: Esta variable permite conocer la coordenada vertical relativa al plano cartesiano en que el mouse se encuentra al momento de estar presionado su botón. Su valor se refresca sólo cuando el mouse está oprimido (si el mouse sólo se pasea sin estar oprimido, el valor de esta variable no se refresca). Por ejemplo, la variable Esp.mouse_y nos indica la coordenada vertical del mouse en el espacio Esp cuando se hace clic con el mismo.

Una forma de identificar las coordenadas del ratón, sin necesidad de apretar el botón, es activar en el espacio el checkbox sensible a los movimiento del ratón, tal como se aprecia en la siguiente figura:


Conocer las posiciones del ratón, en un espacio, es útil para el diseño de objetos interactivos de aprendizaje. En la siguiente escena, puedes evidenciar una aplicación en el plano cartesiano. Desplaza el ratón por cada cuadrante.

Veamos dos variables más para el ratón.

<Nombre del espacio>.mouse_clicked: Esta variable vale la unidad cuando el botón del mouse ha sido soltado tras por lo menos haber hecho clic una vez en el espacio en cuestión. Si el botón del mouse se oprime por primera vez y se mantiene oprimido, su valor es cero. Sólo se vuelve uno hasta soltar el botón mouse. Así pues, nos permite saber si el usuario ha hecho clic en un espacio o no, y siempre y cuando el botón del mouse ya haya sido soltado.

<Nombre del espacio>.mouse_pressed: Esta variable vale la unidad siempre que el botón izquierdo del mouse se encuentra oprimido. Si se suelta dicho botón, el valor de la variable regresa a cero.

Un ejemplo del uso de la variable <Nombre del espacio>.mouse_clicked, lo puedes ver en la siguiente escena interactiva.

Variables de los controles gráficos

Las variables de los controles gráficos se usan para conocer las coordenadas relativas de un control gráfico, así como para asignarle valores a las mismas. También nos permiten saber si un determinado control gráfico está siendo usado o no.

Para usar estas variables es preciso indicar el identificador del control gráfico (sobre el cual se quiere conocer información) mediante un prefijo, que es el identificador del mismo del control. Como notación usamos <Identificador del control> para indicar que ahí va el identificador del control gráfico.

<Identificador del control>.x: Esta variable se puede usar para imprimir el valor de la coordenada horizontal del control gráfico relativa al plano cartesiano. También es posible asignarle un valor a esta variable para colocar el control gráfico en una determinada posición horizontal.

Por ejemplo, la variable g1.x guarda el valor de la coordenada horizontal de un control gráfico con identificador g1.

<Identificador del control>.y: Esta variable se puede usar para imprimir el valor de la coordenada vertical del control gráfico relativa al plano cartesiano.

También es posible asignarle un valor a esta variable para colocar el control gráfico en una determinada posición vertical. Por ejemplo, la variable g1.y guarda el valor de la coordenada vertical de un control gráfico con identificador g1.

Estas dos variables las usamos en el diseño de las secuencias temporales.

<Identificador del control>.activo: Esta variable nos informa si un control está siendo usado o no. En caso afirmativo, su valor es 1 y de lo contrario es 0. Por ejemplo, la variable g1.activo nos indica si el control gráfico g1 está siendo usado o no. Un control gráfico está activo no sólo si el mouse se encuentra oprimido sobre él controlándolo. También se considera activo si se le hizo un clic y es el último objeto que se seleccionó. Es decir, si se hizo clic en el control gráfico, éste seguirá activo hasta que el mouse haga clic en otro lado distinto al control gráfico.

Variable de controles de audio y video

En los capítulo anteriores hemos trabajado con este variable, la cual es <identificador del control>.currentTime que, dándole un tiempo de argumento, posiciona la reproducción en el tiempo indicado del audio o video asociado al control. Igualmente, la usamos para determinar el tiempo de reproducción. Si se ha de mostrar como parte de un texto, es necesario tener activada una animación mientras se reproduce el audio o video puesto que la animación hace que constantemente se refresque el texto que muestra la variable.

Variable general rnd

Esta variable, cuyo nombre viene de random (o aleatorio) genera un valor aleatorio real entre 0 y 1 cada vez que es llamada. A veces se quiere tener un valor aleatorio entero definido en un determinado intervalo.

Para ello es necesario asociar la variable rnd con algunas funciones que nos permitan tener ese comportamiento.

Hagamos un breve ejercicio cuyo propósito es generar parábolas verticales de la forma $y = ax^2 + bx + c$, donde el coeficiente $a$ puede adoptar valores enteros entre -3 y 3 pero sin incluir el cero (si valiera cero, no se tendría una parábola sino una recta); el coeficiente $b$ puede adoptar valores enteros entre -4 y 4 incluyendo el 0; y $c$ puede adoptar valores reales entre 0 y 3.

Este ejercicio es muy ilustrativo en muchos aspectos, especialmente porque cada variable tiene una asignación distinta de valores. Cada vez que presionas el botón Parábola, se generan diferentes valores para a, b y c, de acuerdo a las siguientes instrucciones:


  • La variable a primero extrae un signo de una expresión aleatoria y luego lo multiplica por otra expresión que es el valor entero aleatorio entre 1 y 3. Así, permite los valores -3, -2, -1, 1, 2 y 3 (excluyendo el 0). Nota que aunque hay dos distintos rnd en su asignación, cada uno lleva un valor aleatorio nuevo (no son el mismo valor).
  • La variable b, al no tener la restricción de no poder valer cero, se asigna como el valor -4 al que se le suma un valor aleatorio entero entre 0 y 8, de tal forma que puede adoptar valores entre -4 y +4.
  • La variable c, al no tener la restricción de ser entera, no requiere la función ent() que devuelve el valor entero de su argumento.
  • Las variable rnd, en realidad, tiene su máximo en .99999. Se deja al usuario que analice cuidadosamente qué pasaría si ese máximo fuese uno (1). Considera la variable b: ¿Es probable obtener un valor de +4 para esta variable con la expresión dada?

Funciones intrínsecas de DescartesJS

DescartesJS tiene una variedad de funciones propias, muchas de las cuales son las típicas utilizadas en casi cualquier lenguaje de programación. No obstante, adicionalmente tiene otras propias relacionadas a audio, video, evaluación de funciones, etc. que se revisarán a continuación. Las funciones aquí presentadas se agrupan

según su funcionalidad.

Funciones comunes

  • abs(): Es una función que recibe un argumento y devuelve el valor absoluto del mismo. Por ejemplo, abs(-2) devolverá 2.
  • acos(): Es una función que recibe un argumento y devuelve su arcocoseno en radianes. Por ejemplo, acos(-1) devolverá el valor 3.141... radianes (que son 180°).
  • asin(): Es una función que recibe un argumento y devuelve su arcoseno en radianes. Por ejemplo, asin(1) devolverá el valor 1.570... radianes (o 90°).
  • atan(): Es una función que recibe un argumento y devuelve su arcotangente en radianes. Por ejemplo, atan(1) devolverá el valor 0.785... radianes (que son 45°).
  • cos(): Es una función que recibe un argumento, lo interpreta en radianes, y devuelve el coseno del mismo. Por ejemplo, cos(pi/2) (recordamos que $\frac{π}{2}$ equivale a 90°) devolverá el valor 0.
  • cot(): Es una función que recibe un argumento, lo interpreta en radianes, y devuelve la cotangente del mismo. Por ejemplo, cot(0.785398163) devolverá un valor cercano a 1 pues 0.785398163 radianes es cercano a 45°.
  • csc(): Es una función que recibe un argumento, lo interpreta en radianes, y devuelve la cosecante del mismo. Por ejemplo, csc(pi/2) devolverá un valor de 1.
  • ent(): Es una función que recibe un argumento y devuelve el valor del entero inmediatamente inferior. Por ejemplo, ent(-3.2) devolverá el valor -4.

    Esta variable se puede extender a una que redondea si al argumento se le suma 0.5. Por ejemplo, ent(3.78+0.5) devolverá el valor 4, que es lo mismo que redondear 3.78. Nota también que cuando el argumento es positivo, el valor devuelto consiste siemplemente en truncar al mismo (recortarle los decimales).

  • exp(): Es una función que recibe un argumento y devuelve el valor de la exponencial neperiana del mismo. Por ejemplo, exp(2) devolverá el valor de $e^2$, que es 7.389....
  • _índiceDe_(): Es una función que recibe dos argumentos de tipo cadena de texto. El primero es el texto principal. El segundo es un texto contenido en el primero. La función devuelve un entero que es el índice (contando el primer carácter del texto principal como el cero-ésimo) en el que empieza el texto contenido. Si no encuentra el texto contenido en el texto principal, devuelve un valor de -1. Por ejemplo, _índiceDe_('hola','ola') devolverá el valor 1.
  • log(): es una función que recibe un argumento y devuelve el logaritmo neperiano del mismo. Por ejemplo, log(7.389056099) devolverá un valor cercano a 2, ya que $e^2 =$ 7.389056099....
  • _letraEn_(): Es una función que recibe dos argumentos. El primero es una cadena de texto. El segundo es un entero que corresponde al índice de la letra (empezando a contar la primera letra como la cero-ésima) que devolverá la función. Por ejemplo, _letraEn_('hola',1) devolverá el texto 'o'.
  • _longitud_(): Es una función que recibe un argumento de una cadena de texto y devuelve la longitud en caracteres del mismo. Por ejemplo, _longitud_('hola') devolverá el valor 4.
  • max(): es una función que recibe un par de argumentos numéricos y devuelve el que es mayor de ambos. Por ejemplo max(-6,-3.59) devolverá -3.59.
  • min(): es una función que recibe un par de argumentos numéricos y devuelve el que es menor de ambos. Por ejemplo min(-7,-4.2) devolverá -7.
  • raíz() o sqrt(): Es una función que recibe un argumento y devuelve la raíz cuadrada del mismo. sqrt viene de square root. Por ejemplo, raíz(9) o sqrt(9) devolverá el valor 3.
  • sec(): Es una función que recibe un argumento, lo interpreta en radianes, y devuelve la secante del mismo. Por ejemplo, sec(pi) devolverá un valor de -1.
  • sen() o sin(): Es una función que recibe un argumento, lo interpreta en radianes, y devuelve el seno del mismo. Por ejemplo, sen(pi/2) o sin(pi/2) (recordamos que $\frac{π}{2}$ equivale a 90°) devolverá el valor 1.
  • sgn(): Es una función que recibe un argumento, y de ser éste positivo devuelve el valor +1. De ser el argumento negativo devuelve -1. Es decir, extrae sólo el signo del argumento. Por ejemplo, sgn(-3) devolverá el valor -1.
  • sqr(): Es una función que recibe un argumento y devuelve su valor al cuadrado. Viene de la palabra square. Por ejemplo, sqr(3) devolverá el valor 9.
  • _subcadena_(): Es una función que recibe 3 argumentos. El primero es una cadena de texto, el segundo y tercero son enteros que corresponden a índices de los caracteres de la cadena, contando el primer caracter como el cero-ésimo.

    La función devuelve una cadena de texto que va del índice del segundo argumento (inclusivo) al índice del tercer argumento (exclusivo). Por ejemplo, _subcadena_('hola',1,3) devolverá la cadena 'ol'.

  • tan(): Es una función que recibe un argumento, lo interpreta en radianes, y devuelve la tangente del mismo. Por ejemplo, tan(pi/4) (recordamos que $\frac{π}{4}$ equivale a 45°) devolverá el valor 1.

Existen también funciones trigonométricas hiperbólicas (seno, coseno y tangente). Basta agregar una h al final de cada una (sinh(), cosh() y tanh()). En la siguiente escena interactiva puedes ingresar algunas de la funciones anteriores y verificar el resultado.

Funciones definidas por el usuario

Además de las funciones propias de DescartesJS, podemos definir todas las que queramos o necesitemos en un interactivo en particular, constituyéndose en extensiones o adiciones a las funciones incorporadas. En el capítulo sobre familias ya habíamos dispuesto un texto descriptivo de cómo incorporar o definir nuevas funciones, del cual recordamos:

Las funciones involucran una o un conjunto de instrucciones que se pueden activar sólo en ciertas ocasiones. Tienen la virtud de que se pueden agrupar ciertas instrucciones que se repiten muchas veces a lo largo de un programa en un solo bloque de código.

Un ejemplo que presentamos de definición de función fue el Máximo Común Divisor. En este apartado, presentamos tres ejemplos adicionales, un poco más simples pero que te ayudan a comprender cómo es su funcionamiento.

En la siguiente escena interactiva, en el selector Definiciones, hemos difinido dos funciones, así:

Esta es la escena interactiva:

También es posible definir funciones con dos o más variables. En la siguiente escena interactiva puedes observar dos funciones de varias variables con su respectiva imagen, que ilustra cómo se definieron:

En estos dos ejemplos sólo hemos usado una instrucción para cada función; sin embargo, como se enunció antes, es posible definir una función con varias instrucciones, para ello, tendremos que hacar uso de la opción algoritmo. Un primer ejemplo fue el cálculo del MCD, un segundo ejemplo es el cálculo del factorial de un número entero positivo, que explicaremos con más detalle a continuación.

En primer lugar, definimos la función factorial, así:

Como vamos a usar un algoritmo, hemos asignado a la función factorial la variable f, lo que significa que el cálculo que se haga en el algoritmo para f, será retornado a la función. En segundo lugar, restringiremos los valores del número n al que le calcularemos el factorial, el cual no puede ser negativo:

Observa que hemos activado el checkbox del algoritmo. En tercer lugar, inicializamos un contador i en cero y la variable f en uno (1):

Finalmente, en hacer hemos puesto dos asignaciones. La primera es el contador que tendrá valores de 1, 2, 3, ..., n (recuerda que la asignación i = i + 1 se realiza mientras, i<n).

La segunda asignación, para cada iteración, funcionará así (f = 1*1), (f = 1*2), (f = 2*3), ..., (f = f*n), obteniendo finalmente, el factorial de n.

Este valor de f es retornado a la función.

He aquí el objeto interactivo:

Evaluación final

Para terminar, responde a $10$ preguntas planteadas en la siguiente escena

¡Espera!
Hay algo más

Macros y plantillas

Actividades del capítulo

Al terminar este capítulo, habrás diseñado plantillas como:

Plantilla selección múltiple - cuatro respuestas

Plantilla selección múltiple - cinco respuestas

Macros

Una plantilla es un diseño o esquema predefinido, que podemos reusar en cualquier otra actividad u objeto interactivo. Su uso permite ahorrar esfuerzos en nuestros diseños; por ejemplo, sí estamos diseñando objetos 3D que deben incluir los ejes coordenados y los planos cartesianos, una buena idea es tener una plantilla con estos elementos. Esta plantilla es, entonces, todas las instrucciones para dibujar los ejes $X$, $Y$ y $Z$, además de las puntas de los ejes (conos), y los planos $XY$, $XZ$ y $YZ$:

Este grupo de instrucciones se denomina "macro-instrucciones" o, para simplificar, Macros.

Antes de realizar las actividades que incluyen macros, te recomendamos leer el siguiente texto:

Macros gráficos

En el texto anterior, pudiste observar un ejemplo de un circuito eléctrico que incorpora una macro correspondiente al gráfico de una bombilla, la cual se invoca dos veces para diseñar el circuito. A continuación, diseñaremos una plantilla cuyo objetivo es obtener un gráfico que se dibuje en dos esquinas de la plantilla, es decir, diseñar adornos gráficos para la plantilla. La macro debe permitir su reconfiguración desde la escena que la invoca, tal como se muestra en la siguiente imagen:

Diseño de la macro. Creamos una nueva escena de $600 \times 400$ pixeles. El adorno que usaremos es la curva paramétrica llamada "gota de agua"Véase el libro Curvas y superficies paramétricas (página 53). con algunas variaciones que permitan dibujarla en dos extremos de la escena.

Las curvas paramétricas que definen la gota de agua son: $x = r^2 (cos b)^3 sen(b)$, $y = r^2 (cos b)^2$, con $b$ en el intervalo $[0, π]$. Las variaciones que hemos realizado son dos; la primera es multiplicar estas ecuaciones por 0.2, de tal forma que se reduzca el tamaño de la gota y, la segunda, sumar o restar valores a x e y, para ubicar dos gotas en los extremos.

Agregamos, entonces, el gráfico tipo ecuación tal como se muestra en la siguiente imagen:

Observa que restamos 6 a la abscisa y sumamos 6 a la ordenada, de tal forma que la gota se ubique en el extremo superior izquierdo. Luego copiamos esta curva cambiando de signos los valores sumados a x e y, dibujar una segunda gota en el extremo inferior derecho. Por otra parte, tanto el color de la gota como su relleno los configuramos así:

En el algoritmo INICIO definimos las cinco variables que permitirán reconfigurar la macro que guardaremos a continuación.

La escena que obtenemos es esta:

Puedes desplazar los gráficos con clic sostenido para que observes las gotas.

Finalmente, guardamos la escena como gota.html y creamos la macro exportándola así:

Una vez creada la macro, podemos invocarla desde una escena nueva:

Tal como lo dice el texto sobre macros, podemos intervenir las variables de la macro (r, rojo, verde, azul, transp), anteponiendo el nombre de la macro a dichas variables (g según la imagen anterior); por ejemplo, g.azul=0.5 cambia el valor del componente azul del color y relleno de la gota.

Como ejemplo, hemos agregado dos controles que permitan reconfigurar la macro. El primero de ellos cambia la variable r de la curva:

El segundo control te queda como tarea.

Es importante, para esta macro, que uses escenas del mismo tamaño ($600 \times 400$) y, para todas las macros, que el nombre del espacio sea el mismo del que generó la macro, que para el ejemplo es E1.

A continuación, puedes interactuar con la escena obtenida. Usa valores de r para 15 y 50 y, además, aumenta la tonalidad del rojo.

Macros prediseñadas

Existen varias macros que algunos diseñadores cartesianos han desarrollado en diferentes proyectos. Dos de ellas, por su utilidad, las vamos a explicar detalladamente en este apartado. Para ello, descarga esta carpeta, luego la descomprimes en el lugar donde vas a diseñar las actividades de este capítulo.

Barra Jinich

Esta macro fue diseñada para el proyecto Telesecundaria. La barra aparece inicialmente en un avance del 50%, que irá creciendo hasta el extremo verde o decreciendo hasta el extremo rojo, según la configuración que se dé en la escena que la incorpora. Observa un ejemplo:

Como no se trata de diseñar la macro, sólo nos detenemos a describir su configuración.

Abre, con el editor DescartesJS, la macro Barra_Jinich.html, en la que observarás: En el algoritmo INICIO se definen las siguientes variables: B=0.50; L=600; H=20, donde B corresponde al avance de la barra (50%), L y H son la longitud y la altura de la barra en pixeles. Sólo se usan tres gráficos:

Si observas el color del gráfico segmento, notarás que se define con tres funciones:

Estas funciones usan como variables la longitud de la barra (L) y, obviamente, la variable s de la familia de segmentos; por ejemplo: Rojo(s) = (s<L/2)+(s>=L/2)*(1-(s-L/2)/(L/2)), expresión que garantiza el cambio de tonalidad del rojo. Estas funciones se constituyen en la novedad de esta macro.

En el ejemplo de aplicación que mostramos anteriormente, invocamos la macro Jinich.txt con el nombre barra, así:

La reconfiguramos en el algoritmo INICIO:

Como la variable barra.B es la que hace crecer o decrecer la barra, basta con aumentarla en 0.1 por cada acierto o reducirla en 0.1 en caso contrario. El resto del ejemplo es fácil de diseñar.

La barra Jinich la hemos usado en el proyecto "Plantillas". Observa dos ejemplos (haz clic sobre cada imagen):

Posición aleatoria

En muchos diseños necesitamos que un grupo de objetos aparezcan en un orden aleatorio. Por ejemplo, en las dos actividades del capítulo las respuestas no aparecen en el orden que las escribimos en el archivo de texto, pues al estar la respuesta correcta en el primer lugar, sería demasiado obvio el resto de la actividad. Por ello, optamos por recurrir a una posición aleatoria para que aparezcan las respuestas.

Otra situación puede ser que necesitemos seleccionar n datos de un repositorio que contiene m datos, donde n es menor que m. Para actividades repetitivas, tampoco es conveniente que se seleccionen siempre los primeros n datos; por ello, sería necesario que se escojan aleatoriamente del universo de datos.

Las plantillas ejemplo de la página anterior usan, también, la posición aleatoria. En la primera, los datos son imágenes que no siempre aparecen en el mismo orden. En la segunda, los datos son las coordenadas en el que aparecen las piezas del puzle, que siempre tendrán una posición aleatoria.

A continuación, diseñaremos una escena que usa la macro random.txt, la cual se encuentra en la carpeta que previamente descargaste. En esta carpeta hemos dejado tanto la macro como la escena que le dio origen, así que puedes abrir random.html con el editor DescartesJS y explorar cómo fue diseñada. Para su uso, sólo nos interesa la variable n_numeros (cantidad de números a aleatorizar) y la función creaAleatorios():

Iniciemos, pues, con el diseño de la escena, la cual es de $600 \times 250$ pixeles (en este caso no necesitamos que el tamaño sea igual al de la escena random.html, pero si es necesario que se conserve el nombre del espacio, E1).

En dibujar si hemos puesto cero (0), con el fin de evitar que aparezcan los seis números en posiciones aleatorias que trae por defecto la macro. Hemos invocado dos veces la macro random.txt porque vamos a generar dos grupos de números. La primera macro la hemos llamado azar y la segunda azar2.

El propósito de la escena es que muestre, en primer lugar, cinco números del 1 al 5 en posición aleatoria (5 de 5) y, en segundo lugar, cinco números seleccionados aleatoriamente de los números del 1 al 20 (5 de 20).

La macro random, entonces, genera números enteros del 1 a n_numeros, que luego los posiciona aleatoriamente.

Para el primer grupo de cinco números, usamos las siguientes instrucciones: azar.n_numeros=5; azar.creaAleatorios() (observa que debemos anteponer el nombre de la macro). Para el segundo grupo: azar2.n_numeros=20; azar2.creaAleatorios(). En los resultados a mostrar, debemos usar los vectores azar.resultadoVec[] y azar2.resultadoVec[], obteniendo:

El control tipo botón debe ejecutar las instrucciones anteriores, de tal forma que se generen nuevos grupos de números en posición aleatoria. Haz clic en la siguiente imagen para que observes otro ejemplo.

Diseñando con macros

Vamos a diseñar la primera actividad propuesta al inicio del capítulo, usando dos macros.

Actividad

Diseñar una plantilla para realizar evaluaciones tipo selección múltiple de única respuesta. La respuesta se debe seleccionar de un grupo de cuatro posibles. Para el diseño se debe usar las macro sombras.txt y random.txt, esta última para presentar las posibles respuestas en posiciones aleatorias. Tanto las preguntas como las respuestas se deben almacenar en archivos tipo txt, para ello puedes usar los datos de la Tarea 1.

Iniciemos la actividad abriendo la Tarea 1 con el editor DescartesJS (Si no hiciste la Tarea 1, puedes usar la escena interactivo3.html que se encuentra en la carpeta interactivos de este libro).

A este escena la haremos los siguientes cambios:

  • Cambiamos las dimensiones a $710 \times 500$.
  • En el espacio E1, hacemos este cambio:

Estos dos primeros cambios obedecen a que debemos ajustar la escena para un nuevo entorno gráfico, como lo veremos a continuación.

  • Modificamos los textos que presentan las respuestas, cambiando la abscisas en el campo de texto expresion y el ancho del texto:

Observa que sólo es cambiar -6 por -8 y ajustar el texto a 600 pixeles.

  • Cambiamos las abscisas de las tres curvas de -7 a -9. Lo que obliga a cambiar la condición de la tercera curva por (abs(s-E1.mouse_y)<.5)&(abs(-9-E1.mouse_x)<.5)&(E1.mouse_clicked=1), en coherencia con la nueva abscisa.
  • Subimos un poco el texto de la pregunta cambiando la expresión (0,6.5) por (0,6.8) y cambiamos el tamaño de la letra a 20 (igual para las respuestas)

Hasta aquí hemos hecho cambios a los objetos gráficos existentes en la Tarea 1. Ahora, vamos a incorporar tres macros, tres rectángulos y cinco textos nuevos.

Macro sombras

Esta macro fue diseñada para el proyecto "Pizarra Interactiva", la cual tiene una función similar a la que vimos en la macro gota: es decir, un adorno en las esquinas de la escena.

  • Agregamos, entonces, dos macros sombras.txt, así:
  • La primera la llamamos adorno en la posición [0,0], la segunda tiene el nombre adorno2 en la posición [710,500]. Estas posiciones corresponden a las esquinas donde se ubican estas macros gráficas, lo que significa que puedes ajustarlas a tu gusto (obviamente, debes haber copiado las macros en una carpeta donde tienes la Tarea 1).

  • Agregas, también, la macro random.txt, asegurándote de asignar cero (0) en la casilla de texto dibujar si.
  • Ahora, dibujaremos tres rectángulos, tal como se indica en la imagen de la derecha (haz clic sobre la imagen para ver mejor la configuración).
  • Cada rectángulo tiene radio del borde de 20, que puedes cambiar.

    El segundo rectángulo es una familia de cuatro, que se convierten en los contenedores de las respuestas.

    El tercer rectángulo colorea de verde la respuesta correcta, una vez se haya seleccionado la respuesta y cliclado en el botón verificar.

    Se indican los colores de relleno de los rectángulo, sugerimos un color un poco más obscuro para los bordes.

Es importante que los rectángulos estén al inicio, para evitar que se superpongan a los textos.

Luego retornamos al selector Gráficos para agregar los cinco textos nuevos.

  • Agregamos un control tipo botón, el cual permitirá mostrar los resultados de la evaluación. Este botón tendrá la siguiente configuración:
  • En el selector Definiciones modificamos las instrucciones dadas para la función calcula_posiciones() por:

En este caso hemos usado los resultados de la macro random, la cual posiciona las respuestas aleatoriamente.

En el algoritmo INICIO haremos cambios significativos. En primer lugar, modificamos los colores de los adornos de las esquinas, de tal forma que tenga tonalidades similares a las dadas a los rectángulos.

En segundo lugar, hemos definido el número de preguntas como el primer elemento del vector NP[], que luego definiremos.

Por último, calculamos las posiciones aleatorias de las preguntas, antes de invocar la función calcula_posiciones()


  • En el algoritmo CALCULOS sólo tenemos que cambiar la abscisa -7 por -9:

Ahora sólo nos falta configurar los vectores con las preguntas y respuestas, para retornar al selector Gráficos y agregar los últimos cincos textos.

La creación de vectores con datos externos la explicamos en la siguiente presentación:

La expresión "Hemos creado una plantilla" es una afirmación, que se justifica porque la escena obtenida permite, con un editor HTML, modificar los <script> sin necesidad de intervenir con el editor DescartesJS, es decir, podemos cambiar el número de preguntas, las preguntas y respuestas y obtener una nueva escena.

También pudiste observar que en la escena final ya aparecen los cinco textos que nos falta diseñar.

Todos estos textos los ubicaremos en las coordenada relativas (0,-4.5) y con punto de anclaje centro-centro:

  • Primer texto. Haz clic en el círculo de la respuesta correcta, el cual se mostrará si (ver=0)&(pregunta=1)&(E1.mouse_clicked=0), su tamaño es 23 y color azul.
  • Segundo texto. Ninguna respuesta correcta... ¡Muy lamentable!, el cual se mostrará si (ver=2)&(buenas=0), su tamaño es 25 y color rojo.
  • Tercer texto. Sólo una respuesta correcta... ¡Lamentable!, el cual se mostrará si (ver=2)&(buenas=1), su tamaño es 25 y color naranja.
  • Cuarto texto. Respondiste [buenas] respuestas correctas de [total_preguntas] preguntas, el cual se mostrará si (ver=2)&(buenas>1)&(buenas<total_preguntas), su tamaño es 25 y color brown.
  • Quinto texto. ¡Excelente! Todas las respuestas correctas, el cual se mostrará si (ver=2)&(buenas=total_preguntas), su tamaño es 25 y color verde.

Tarea

Modifica la escena de tal manera que se obtenga una plantilla de selección múltiple de única respuesta con cinco opciones de respuesta, tal como lo mostramos en la segunda escena al inicio del capítulo, la cual puedes abrir aquí.

¡Eso es todo en este curso!