Les vencimos

1º Bachillerato · TIC I

Lección 25 · C · Programación

Variables, tipos y operadores

1º Bachillerato · TIC I · Decreto 40/2022 CyL

Objetivos

  1. Declarar variables y nombrarlas por lo que guardan, no por la letra que sobre.
  2. Distinguir número, cadena y booleano, y decir el tipo de una expresión.
  3. Usar operadores aritméticos y de comparación sin mezclarlos con la prosa.
  4. Ver que en JavaScript == y === no son el mismo gesto, y que el laboratorio compara sin convertir.
  5. Relacionar int, const y HIGH/LOW del sketch con los tipos de esta página.

Explicación

Una variable es un nombre atado a un valor que puede cambiar. El nombre es para quien lee el programa; el valor es para la ejecución. luz = 420 significa: a partir de esta línea, y hasta que otra asignación la cambie, el nombre luz vale 420. No es una ecuación de matemáticas: en matemáticas luz = luz + 1 no tiene solución; en un programa es «toma el valor actual, súmale uno y guárdalo otra vez».

Nombres

umbral dice más que u. deNoche dice más que flag. Un nombre corto que el grupo ha acordado vale; un nombre que solo entiende quien lo escribió el martes no vale el jueves. No se pueden dejar espacios, y en este laboratorio el nombre empieza por una letra. Mayúsculas y minúsculas distinguen: Luz y luz son dos cajas. Eso pilla a quien viene de un cuaderno donde la letra no cambia el sentido.

Tipos que usamos ya

El número sirve para la lectura, el umbral, un índice y una cuenta. La cadena es texto entre comillas: "patio", "HIGH". El booleano es verdadero o falso, y casi siempre nace de una comparación: luz < umbral. HIGH y LOW, en el sketch, son nombres de constantes para los dos estados de un pin digital; en la página los escribimos como cadenas o los representamos con el interruptor. No son un tercer tipo mágico: son los dos valores de una salida digital.

El tipo importa porque las operaciones no significan lo mismo. El + entre números suma. En JavaScript, el + entre cadenas concatena, y el + entre un número y una cadena convierte el número en texto: "2" + 3 da "23", no 5. Esa conversión silenciosa es una fuente clásica de avisadores que no encienden: el umbral se leyó como texto de un campo y la comparación ya no es la que creías. En el pseudocódigo de esta página, el + también concatena si alguno de los dos lados es cadena, para que veas el fenómeno. Las comparaciones == y ===, en cambio, aquí no convierten: 2 == "2" es falso. En JavaScript de verdad, 2 == "2" es verdadero y 2 === "2" es falso. Lo diremos en voz alta cada vez que alguien traiga un ejemplo de internet.

Operadores

Suma, resta, producto, división y resto (%). El resto sirve para saber si un índice es par o para quedarte con las dos últimas cifras de una lectura: 420 % 100 es 20.
420 ÷ 100 da cociente entero 4
4 × 100 = 400
420 − 400 = 20 La división entre cero detiene la ejecución: no hay un «infinito» útil para el LED. Las comparaciones son < > <= >= == !=. Un solo = es asignación, no pregunta. Escribir si luz = 500 no pregunta si son iguales: en muchos lenguajes guarda 500 y sigue, que es peor que un error. Aquí el laboratorio rechaza ese = dentro del si.

Declarar y volver a usar

let luz = 420 declara y guarda. Una línea luz = 430 posterior cambia el valor, y solo es legal si luz ya existe: así se pillan las erratas de nombre. const, en JavaScript, es un nombre que no puedes reasignar. En el sketch, const int UMBRAL = 500 hace el mismo oficio de intención: el umbral no debería moverse a mitad de loop. Puedes usar otro nombre si el experimento cambia el umbral, pero entonces es otro experimento y la memoria lo dice.

El pin como dato

El interruptor de la página no modifica solo el dibujo: lee pulsador crea una variable pulsador con 1 o 0. Ese número es un dato más. Puedes comparar pulsador == 1. No compares pulsador == "ON": son tipos distintos y, en este laboratorio, la igualdad no convierte. En la UNO, digitalRead devuelve HIGH o LOW, que se pueden comparar con esas constantes. En la Pi, is_pressed es un booleano. Tres escrituras, la misma idea: la entrada digital cabe en un valor con dos estados.

Cuando ejecutas, el canvas dibuja cada número como una barra y escribe el tipo al lado. Si deNoche sale como cadena, la comparación no se ha hecho: se ha guardado texto. Esa comprobación visual es parte de la lección, no un extra. La salida escribe muestra el valor en la zona de texto. Nada de eso sale del ordenador.

Variables con tipo y valor luz tipo: número 420 umbral tipo: número 500 deNoche tipo: booleano sí
El tipo no es el nombre. luz puede valer 420 (número) o, si alguien se equivoca, la cadena "420", y la comparación ya no es la misma.

Glosas de esta lección

Variable. Nombre ligado a un valor. El valor puede cambiar con otra asignación.

Tipo. Clase del valor: número, cadena, booleano o, más adelante, vector.

Asignación. Un solo =. Guarda. No pregunta.

Comparación. == o <. Pregunta. No guarda.

Resto. % . Lo que sobra al dividir. 420 % 100 es 20.
420 ÷ 100 da cociente entero 4
4 × 100 = 400
420 − 400 = 20

Cadena. Texto entre comillas. "23" no es el número 23.

Booleano. verdadero o falso. Resultado típico de una comparación.

const. Nombre que no se reasigna. En el sketch, el umbral y el número de pin.

Coerción. Conversión automática de tipo. En JavaScript, "2"+3 es "23". Aquí el + lo imita; el == no.

HIGH/LOW. Dos estados de un pin digital. En la página, ON/OFF del GPIO 18 simulado.

Ejemplos resueltos

Ejemplo 1 — Suma que concatena

let umbral = "500" y let raro = umbral + 1. El resultado es la cadena "5001", no 501. La comparación raro < 600 ya no significa lo que el grupo cree. Se guarda el umbral como número desde el principio.

Ejemplo 2 — Un igual en el si

si luz = 500. El laboratorio lo señala como condición mal escrita. Se cambia a luz == 500 o, si la regla del patio es estricta, a luz < 500.

Ejemplo 3 — Nombre reciclado

i guarda la luz y, tres líneas más abajo, i guarda el contador del bucle. La traza se vuelve ilegible. luz e i son dos variables.

Decisiones de aula

Cada caso es una entrega del avisador del patio del IES Duero (Aranda de Duero). Lee la situación antes de la decisión.

1. Letra suelta

Situación. El programa dice a = 420 y b = 500.

No conviene. Porque es más corto y «ya se entiende» en el grupo.

Decisión. Renombrar a luz y umbral antes de seguir con el if.

Por qué: a = 420 y b = 500 se entienden hoy en el grupo y dentro de una semana no. El nombre es la documentación que no se pierde: luz y umbral dicen el papel de cada caja. Un nombre corto acordado vale; una letra suelta no, porque el programa se lee sin el autor delante.

2. Umbral entre comillas

Situación. El valor se copió de un párrafo, con comillas.

No conviene. Comparar igualmente, «porque se ve el 500».

Decisión. Quitar las comillas y comprobar en el canvas que el tipo es número.

Por qué: Un umbral copiado con comillas es texto, y la comparación con texto no es la comparación del sensor. El LED obedecería otra regla, aunque se vea el 500. Se quitan las comillas y se comprueba que el tipo sigue siendo número.

3. Reasignar el pin

Situación. A mitad del algoritmo alguien hace let LED = "rojo" cuando LED era 13.

No conviene. Aprovechar el nombre, total está libre.

Decisión. Dejar el número de pin en un nombre que no se reasigna y usar otro nombre para el color del dibujo.

Por qué: Reutilizar el nombre LED para guardar "rojo" cuando era 13 rompe el paralelo con digitalWrite. Quien traduzca el programa a la placa ya no tiene un número de pin. El pin se queda en un nombre numérico y el color, si hace falta, vive en otro.

4. Resto para el umbral

Situación. Usan % donde querían dividir.

No conviene. Porque el símbolo «se parece» a una raya.

Decisión. Usar / para el cociente y % solo cuando se busca el sobrante, y probar 420 % 100 en el editor.

Por qué: El resto % no se adivina por la forma del símbolo: no es una raya de dividir. / da el cociente y % da lo que sobra. Una traza de una línea, con un número conocido, fija cuál se quería antes de usarlo en el umbral.

El mismo avisador, en tres lenguajes

El problema no cambia: si la luz del patio del IES Duero baja de 500, hay que avisar. Cambia quién ejecuta. El pseudocódigo lo ejecuta el laboratorio de esta página. El sketch lo compilaría el IDE de Arduino hacia la UNO. El fragmento de Python lo ejecutaría una Raspberry Pi con gpiozero, si hubiera placa. Aquí no hay placa.

Tipos en el pseudocódigo

deNoche es booleano. resto es número. lugar es cadena.

let luz = 420
let lugar = "patio"
let deNoche = luz < 500
let resto = luz % 100

Tipos en el sketch

int es entero, bool es booleano, HIGH y LOW son los dos estados del pin 13. El ternario del sketch equivale a un si / si no.

const int LED = 13;
const int UMBRAL = 500;
int luz = analogRead(A0);
bool avisar = luz < UMBRAL;
digitalWrite(LED, avisar ? HIGH : LOW);

Tipos en la Pi

En Python el tipo viaja con el valor. led.value a 1 o 0 es el HIGH/LOW del GPIO 18. La página no ejecuta este archivo.

umbral = 500          # int
lugar = "patio"       # str
de_noche = 420 < umbral  # bool
from gpiozero import LED
led = LED(18)
led.value = 1 if de_noche else 0

Traza con las lecturas del patio

HoraTipo de luzluz < 500Cadena de salidaValor digital
17:30420 · númeroverdaderoHIGH1
17:32510 · númerofalsoLOW0
17:35390 · númeroverdaderoHIGH1
17:41600 · númerofalsoLOW0
17:48500 · númerofalsoLOW0
18:02250 · númeroverdaderoHIGH1
18:15880 · númerofalsoLOW0
18:27499 · númeroverdaderoHIGH1

La columna booleana no es el pin: es la pregunta. La cadena HIGH es una forma de escribir la salida para una persona. El 1 o el 0 es la forma de escribirla para un pin. Son representaciones del mismo hecho, y por eso no se suman entre sí.

Lectura guiada

Prueba en el editor luz = 500 y deNoche = luz < 500, y luego luz == 500. Tienes que obtener falso y verdadero, en ese orden de ideas: no está por debajo, y sí es igual. Si tu regla de avisador usa solo <, el empate no enciende. Escríbelo al lado del tipo booleano para no reabrir el debate en la lección del if.

El resto 1023 % 2 y 500 % 100 no son adornos. El primero te dice si un entero es impar; el segundo te deja las decenas y unidades de una lectura.
1023 % 2: 511 × 2 = 1022
1023 − 1022 = 1
500 % 100: 5 × 100 = 500
500 − 500 = 0 Ninguno sustituye a la comparación del umbral. Sirven para que el operador % tenga un sitio concreto y no se use por inercia.

JavaScript guarda también undefined y null, y más adelante verás objetos. No hace falta agotarlos hoy. Hace falta no mentir el tipo de las tres cosas que ya mueven el avisador: la lectura, el umbral y el estado del pin.

Errores que se repiten

Rúbrica de esta lección

CriterioAún noEn procesoConseguidoNotable
Nombresa, b, cMezcla siglasluz, umbral, deNocheEl pin no se reutiliza como texto
TiposTodo valeHay comillas dudosasNúmero, cadena y booleano correctosExplica un + que concatenaría
Operadores= dentro del siSolo + y -< y == bien usados% o / con una traza
TrazaNo se ejecutaSe ejecuta y no se leeEl canvas coincide con el editorEl caso 500 está anotado
PlacaHIGH es un colorNombra el LEDint, bool y D13 o GPIO 18Recuerda que == de JS convierte

Mini cierre

Cada valor tiene tipo, cada = guarda y cada comparación pregunta. Si el tipo de umbral no es número, el avisador ya no es el del patio aunque el LED se mueva.

Comprueba

Abre cada pregunta, responde en el cuaderno y después mira la solución. El párrafo «Por qué» es la parte que se estudia.

1. ¿Qué vale "2" + 3 en JavaScript, y qué debería haber pasado si ambos fueran lecturas?

Respuesta. Vale la cadena "23". Si fueran lecturas numéricas, la suma sería 5.

Por qué: El + está definido de dos maneras y el lenguaje elige la de las cadenas en cuanto uno de los lados es texto. Por eso un umbral copiado con comillas no «casi» funciona: construye otro número, el 5001, o un texto que ya no se compara como el sensor.

2. ¿Por qué si luz = 500 es un error de esta lección y no una comparación rara?

Respuesta. Porque un solo igual asigna. La condición tiene que usar == o una desigualdad.

Por qué: En varios lenguajes esa asignación además deja la condición en un valor que siempre entra al sí. El LED se quedaría encendido y la traza mentiría. Rechazarlo aquí es más claro que imitar ese comportamiento.

3. analogRead devuelve un entero y is_pressed devuelve un booleano. ¿Puedes usarlos en la misma comparación sin decir el tipo?

Respuesta. No, si quieres que otra persona repita la traza. Hay que saber qué se está comparando con 500 y qué se está comparando con verdadero.

Por qué: El algoritmo es el mismo solo en la estructura (entrada, decisión, pin). Los tipos concretos cambian con el aparato. Escribirlos evita traducir un 1 de la Pi como si fuera una lectura de 10 bits de la UNO.

En la vida real

Castilla y León, sin servidor

  • La hoja de registro del laboratorio de física ya separa número y nota al margen. La variable hace esa separación en el programa.
  • En un formulario del centro, un código postal con cero a la izquierda es texto. Si lo guardas como número, el cero se pierde. El mismo accidente le puede pasar a una lectura si la conviertes mal.
  • El parte de guardia no suma «tarde» + 1. El programa tampoco debería.
  • Cuando en el aula de Zamora solo hay una UNO para ocho personas, la traza de tipos en esta página permite que los ocho corrijan antes de tocar el pin 13.
Laboratorio · en esta página Abrir en pestaña →

El editor admite números, cadenas entre comillas, verdadero/falso, vectores y las operaciones + - * / % y las comparaciones. == no convierte tipos: en este pseudocódigo compara tal cual. El canvas dibuja el estado. Local.

GPIO 18

Simulación local · sin hardware

Raspberry Pi (BCM) · paralelo didáctico Arduino UNO D13 · pin GPIO 18

Estado del pin: LOW · LED apagado

OFF

El interruptor no es una variable hasta que el programa la lee. ON es 1 (HIGH); OFF es 0 (LOW). HIGH enciende el LED (en la Pi, 3,3 V; en Arduino UNO el paralelo didáctico es digitalWrite HIGH en D13). No se envía nada fuera de esta página.

Pulsa Ejecutar. El resultado se queda en esta página.

Escribes y dibujas aquí mismo: no hay salto a otro módulo. La misma herramienta, a pantalla completa, está en l25-variables-tipos-y-operadores.html y en el marco (útil si el navegador permite file:// en iframes).

Reto Profesor

Tres tipos y un pin

En el editor declara la luz como número, el lugar como cadena y un booleano que sea la comparación con tu umbral. Ejecuta y comprueba en el canvas que los tipos coinciden. Añade lee pulsador y una comparación pulsador == 1. Anota en el cuaderno qué pasa con el caso igual al umbral y qué haría const int UMBRAL en el sketch. No uses un solo = dentro de un si.

reto_id: bach1-tic-L25