Campo Calculado (Script)
Introducción
Campos calculados permiten la creación de fórmulas matemáticas que usan valores asociados a las respuestas para calcular valores diversos, tales como promedios, valores máximos, mínimos, desviaciones estándar, etc.
Para construir una fórmula puedes usar cualquier tipo de campo/respuesta que tenga un valor numérico atribuido.
Vea abajo la lista de cuestiones que poseen o pueden poseer valores numéricos asociados y pueden ser usadas en una fórmula:
- Cuestiones numéricas (Enteros, decimales y cantidad usando Emojis)
- Cuestiones de selección única (Menu suspenso, Radio y Botones)
- Cuestiones de selección múltiple (Cajas de selección y Botones)
- Cuestiones de fecha y hora
- Cuestiones de evaluación (Expresiones faciales y Emojis)
- Cuestiones de envío de archivos (número de archivos enviados)
Creando una fórmula simple
Imagina que quieras crear una fórmula que calcule el peso promedio de una serie de muestras de determinado producto. Así, imagina que el formulario tenga las siguientes cuestiones:
- Peso de la muestra 1
- Peso de la muestra 2
- Peso de la muestra 3
En este caso, cada pregunta debe ser configurada con un nombre de campo único, por ejemplo,
peso_amostra_1
, peso_amostra_2
y peso_amostra_3
.
// TODO: Adicionar imágenes
Para esto, debes crear un campo calculado y, a continuación, agregar la fórmula deseada:
function calculateValue() {
return (resp.peso_amostra_1.number
+ resp.peso_amostra_2.number
+ resp.peso_amostra_3.number) / 3;
}
Vamos analizar cada parte de la fórmula:
function calculateValue()
es la función que será ejecutada para calcular el valor del campo calculado. Esa función no puede ser renombrada, ella debe siempre tener ese nombre, no puede recibir parámetros y debe retornar un valor numérico onull
(nulo/vacío).resp
es un objeto que contiene todas las respuestas del formulario.resp.peso_amostra_1
es una estructura que contiene los datos asociados a la respuesta de la preguntapeso_amostra_1
, tales como:number
es el valor numérico de la respuestaname
es el nombre del campo de la pregunta, ej.:peso_amostra_1
tags
es una lista detags
asociadas a la pregunta- Por fin, la fórmula calcula el promedio aritmético de los valores de las respuestas, sumando
peso_amostra_1
,peso_amostra_2
,peso_amostra_3
y dividiendo por 3.
Puedes usar cualquier nombre para las variables, pero es recomendado que uses nombres que tengan sentido para tu formulario.
El editor de código posee autocomplete
, es decir, él sugerirá los nombres de variables y funciones disponibles para que uses en la fórmula.
Puedes usar las teclas Ctrl+Space
o Ctrl+Shift+Space
para activar el autocomplete manualmente.
Atributos generales de las respuestas
Todas las respuestas poseen como mínimo tres atributos: name
, tags
y uno o más atributos específicos
del tipo de respuesta, por ejemplo, number
para cuestiones numéricas, text
para cuestiones de texto, etc.
name
name: string
Nombre de la pregunta. Ejemplo: peso_amostra_1
tags
tags: string[];
Lista de etiquetas de la cuestión, ejemplo: ['peso', 'amostra']
Las tags
son usadas para agrupar cuestiones y facilitar la creación de fórmulas.
Por ejemplo, para calcular el promedio de los pesos de varias muestras, basta colocar una etiqueta
en cada cuestión de peso, por ejemplo, #peso
, y usar esa etiqueta en la fórmula:
function calculateValue() {
return avgByTag('#peso');
}
Donde avgByTag
significa: "average by tag", es decir, "promedio por etiqueta".
Atributos específicos de las respuestas
Vea abajo la lista de atributos específicos disponibles para cada tipo de respuesta:
text
text?: string;
Contenido textual de la respuesta, disponible para cuestiones del tipo:
- Texto de una línea
- Texto de varias líneas
El carácter "?" indica que el atributo es opcional, es decir, puede o no existir. Si el usuario responde a la cuestión el atributo existirá, de lo contrario, no existirá.
label
label?: string;
Etiqueta o Texto vinculado a la opción seleccionada, disponible para cuestiones del tipo:
- Selección única
- Selección múltiple
- Expresiones faciales
number
number?: number;
Contenido numérico de la respuesta, sea el contenido proporcionado por el usuario, sea el contenido numérico vinculado a la opción seleccionada. Disponible para cuestiones del tipo:
- Números enteros
- Números decimales
- Cantidad usando Emojis
- Fórmula matemática
- Selección única/simple
- Expresiones faciales
- Tiempo/Hora
dateStr
dateStr?: string;
Fecha en forma de texto (string).
Formato: YYYY-MM-DDTHH:MM:SSZ
, ej.: 2030-12-31T23:59:59Z
Disponible para cuestiones del tipo:
- Fecha
- Fecha y hora
lat
lat?: number;
Latitud de la coordenada geográfica informada en la respuesta
lon
lon?: number;
Longitud de la coordenada geográfica informada en la respuesta
items
items?: ISelectedItem[];
Lista de ítems seleccionados, disponible para cuestiones del tipo:
- Selección múltiple
- Ordenación
Cada ítem de la lista de items
posee los siguientes atributos:
label: string
: Etiqueta o Texto vinculado a la opción seleccionada.number?: number
: Contenido numérico de la opción seleccionada.position?: number
: Número que representa el orden elegido por el usuario para el ítem seleccionado. Disponible solo en las cuestiones del tipoOrdenación
Funciones disponibles
Las funciones abajo son herramientas que auxilian en la creación de fórmulas, permitiendo que realices cálculos complejos en decenas o centenas de respuestas con apenas una línea de código.
all
function all(): IResponse[];
Retorna una lista (array) con todas las respuestas existentes hasta el momento de ejecución del código, es decir, las respuestas de las preguntas que aparecen antes de este elemento.
Note que no siempre existirá respuesta para una pregunta posicionada antes de la fórmula, pues las preguntas pueden ser "saltadas" por medio de una lógica de navegación o simplemente no ser respondidas.
Esta advertencia vale para todas las funciones que retornan una lista de respuestas.
findByTag
function findByTag(oneOrMoreTagNames: string | string[]): IResponse[];
Retorna una lista (array) con las respuestas que poseen las etiquetas especificadas.
Solo las preguntas que aparecen antes de este elemento serán analizadas.
Ejemplo:
La función abajo retorna la cantidad de respuestas que poseen la etiqueta #peso
, es decir,
la cantidad de muestras completadas por el usuario.
function calculateValue() {
const qntAmostras = findByTag('#peso').filter(r => hasContent(r.number)).length;
return qntAmostras;
}
avgByTag
function avgByTag(...oneOrMoreTagNames: string[]): number;
Calcula el promedio de los valores numéricos de las respuestas que poseen las etiquetas especificadas.
Respuestas que no poseen valor numérico son ignoradas.
Solo las preguntas que aparecen antes de este elemento serán analizadas.
Evita calcular promedios de forma manual, pues si alguna de las respuestas está en blanco (no completada) el resultado final podrá diferir de lo esperado.
Ej.: Si usas la siguiente fórmula para calcular el promedio de 3 pesos: (peso1 + peso2 + peso3) / 3
, el resultado
solo será correcto si las 3 muestras son completadas. De lo contrario, el resultado será incorrecto.
Imagina que el usuario completó solo 2 muestras, es decir, peso1
y peso2
, y dejó la tercera muestra en blanco,
en este caso, el resultado de la fórmula será: (peso1 + peso2) / 3
, que es diferente del resultado correcto: (peso1 + peso2) / 2
.
Para evitar este tipo de situación, se recomienda usar la función avgByTag
para calcular el promedio,
pues ella trata adecuadamente las respuestas en blanco, es decir, el resultado será siempre correcto.
sumByTag
function sumByTag(...oneOrMoreTagNames: string[]): number;
Calcula la suma de los valores numéricos de las respuestas que poseen las etiquetas especificadas.
Solo las preguntas que aparecen antes de este elemento serán analizadas.
countByTag
function countByTag(...oneOrMoreTagNames: string[]): number;
Retorna la cantidad de respuestas que poseen las etiquetas especificadas.
Solo las preguntas que aparecen antes de este elemento serán analizadas.
maxByTag
function maxByTag(...oneOrMoreTagNames: string[]): number | undefined;
Retorna el mayor valor numérico existente en las respuestas que poseen las etiquetas especificadas o 'undefined' en caso de que ningún valor sea encontrado.
Respuestas que no poseen valor numérico son ignoradas.
Solo las preguntas que aparecen antes de este elemento serán analizadas.
minByTag
function minByTag(...oneOrMoreTagNames: string[]): number | undefined;
Retorna el menor valor numérico existente en las respuestas que poseen las etiquetas especificadas o 'undefined' en caso de que ningún valor sea encontrado.
Respuestas que no poseen valor numérico son ignoradas.
Solo las preguntas que aparecen antes de este elemento serán analizadas.
hasContent
declare function hasContent(value: any): boolean;
Retorna true
en caso de que el valor informado sea diferente de undefined
, null
, []
o una string vacía (''
).
isEmpty
declare function isEmpty(value: any): boolean;
Retorna true
en caso de que el valor informado sea undefined
, null
, []
o una string vacía (''
).
Ejemplos
Ejemplo 1
En este ejemplo mostraremos cómo calcular los valores de la Fórmula de Bhaskara. El objetivo de este ejemplo es mostrar cómo almacenar valores parciales en variables y cómo usar esos valores para realizar cálculos más complejos.
En este ejemplo veremos, también, cómo usar funciones matemáticas predefinidas, como Math.sqrt
y Math.pow
.
Definición de la fórmula de Bhaskara:
function calculateValue() {
let a = resp.a.number;
let b = resp.b.number;
let c = resp.c.number;
let delta = Math.pow(b, 2) - 4 * a * c;
let x1 = (-b + Math.sqrt(delta)) / (2 * a);
let x2 = (-b - Math.sqrt(delta)) / (2 * a);
return x1; // o x2
}
Donde:
Math.pow(b, 2)
es equivalente a b²
Math.sqrt(delta)
es equivalente a √delta
Ejemplo 2
En este ejemplo veremos cómo calcular la secuencia de Fibonacci. El objetivo de este ejemplo es mostrar que es posible definir y usar funciones diversas, inclusive funciones recursivas, permitiendo así, la creación de cálculos más complejos.
function calculateValue() {
const n = resp.any_question_answer.number;
return fibonacci(n);
}
function fibonacci(n: number): number {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
Funciones matemáticas predefinidas
Nombre | Descripción |
---|---|
abs(x) | Retorna el valor absoluto de x |
acos(x) | Retorna el arco coseno de x, en radianes |
acosh(x) | Retorna el arco coseno hiperbólico de x |
asin(x) | Retorna el arco seno de x, en radianes |
asinh(x) | Retorna el arco seno hiperbólico de x |
atan(x) | Retorna el arco tangente de x como un valor numérico entre -PI/2 y PI/2 radianes |
atan2(y, x) | Retorna el arco tangente del cociente de sus argumentos |
atanh(x) | Retorna el arco tangente hiperbólico de x |
cbrt(x) | Retorna la raíz cúbica de x |
ceil(x) | Retorna x, redondeado hacia arriba al entero más próximo |
clz32(x) | Retorna el número de ceros a la izquierda en una representación binaria de 32 bits de x |
cos(x) | Retorna el coseno de x (x está en radianes) |
cosh(x) | Retorna el coseno hiperbólico de x |
exp(x) | Retorna el valor de Ex |
expm1(x) | Retorna el valor de Ex menos 1 |
floor(x) | Retorna x, redondeado hacia abajo al entero más próximo |
fround(x) | Retorna la representación flotante más próxima (precisión única de 32 bits) de un número |
log(x) | Retorna el logaritmo natural de x |
log10(x) | Retorna el logaritmo de base 10 de x |
log1p(x) | Retorna el logaritmo natural de 1 + x |
log2(x) | Retorna el logaritmo de base 2 de x |
max(x1,x2,..) | Retorna el número con el mayor valor |
min(x1,x2,..) | Retorna el número con el menor valor |
pow(x, y) | Retorna el valor de x elevado a y |
random() | Retorna un número aleatorio entre 0 y 1 |
round(x) | Redondea x al entero más próximo |
sign(x) | Retorna el signo de un número (verifica si es positivo, negativo o cero) |
sin(x) | Retorna el seno de x (x está en radianes) |
sinh(x) | Retorna el seno hiperbólico de x |
sqrt(x) | Retorna la raíz cuadrada de x |
tan(x) | Retorna la tangente de un ángulo |
tanh(x) | Retorna la tangente hiperbólica de un número |
trunc(x) | Retorna la parte entera de un número (x) |
Constantes matemáticas predefinidas
Nombre | Descripción |
---|---|
Math.E | Retorna el número de Euler (aprox. 2,718) |
Math.PI | Retorna PI (aprox. 3,14) |
Math.SQRT2 | Retorna la raíz cuadrada de 2 (aprox. 1,414) |
Math.SQRT1_2 | Retorna la raíz cuadrada de 1/2 (aprox. 0,707) |
Math.LN2 | Retorna el logaritmo natural de 2 (aprox. 0,693) |
Math.LN10 | Retorna el logaritmo natural de 10 (aprox. 2,302) |
Math.LOG2E | Retorna el logaritmo de base 2 de E (aprox. 1,442) |
Math.LOG10E | Retorna el logaritmo de base 10 de E (aprox. 0,434) |