Revisión de los 17 algoritmos, uno por uno, buscando escribirlos de forma más clara sin cambiar en nada lo que hacen. Se escribieron como propuestas; la franja de abajo dice cuáles se aplicaron después.
Este documento se escribió como un conjunto de propuestas. Desde entonces se aplicaron, y la verificación de equivalencia se volvió a correr sobre los archivos nuevos: las 17 actividades siguen siendo equivalentes, y con el resultado más limpio que ha dado la medición — las 17 con isomorfismo y distancia de edición 0, mismo número de nodos y de aristas en los dos lados. La refactorización no costó ni un punto de equivalencia, que es exactamente lo que el método pretendía garantizar por construcción.
Una corrección que nos toca a nosotros, no al código. La versión anterior de la revisión de equivalencia dejaba en la actividad 12 una «pregunta abierta» sobre el redondeo, diciendo que micro:bit redondeaba al entero más cercano y Protobject hacia arriba. Era falso: las dos redondean hacia arriba, y ya lo hacían antes. El fallo estaba en el programa que lee los bloques, que descartaba el campo que dice de qué tipo de redondeo se trata. Ya está corregido, y la pregunta se retiró.
Antes de mirar nada, el margen de maniobra quedó fijado. Buena parte de las propuestas que aquí no aparecen fueron descartadas por una de estas tres reglas, no por falta de ideas.
| Solo la forma | Lo que se ve y se oye tiene que quedar idéntico: los mismos píxeles, en el mismo orden, con las mismas pausas y los mismos sonidos. Una mejora que cambie el comportamiento —aunque sea para bien— no es una refactorización: es un rediseño, y esa es una decisión aparte. |
| La progresión manda | Cada actividad solo puede usar construcciones ya introducidas en ella o antes. El condicional aparece
en la 6ª, el si no en la 7ª, las variables en la 9ª, el ciclo contado en la 14ª, el
mientras en la 15ª. Varias reescrituras obviamente mejores están prohibidas por esto, y se
dejan anotadas para que no se vuelvan a proponer. |
| Solo vocabulario común | Se pueden usar 34 de los 39 nodos de la ontología: los 5 restantes existen en una sola plataforma
(ClearTextDisplay, NoiseToColour, SerialWrite,
SetBackgroundColor, SetTextSize) y usarlos rompería la equivalencia. |
De las 17, siete no necesitan ningún cambio — y eso es un resultado, no una omisión. De las diez restantes, seis se arreglan sin tocar un solo bloque ejecutable.
| Actividad | Veredicto | Qué cambia | |
|---|---|---|---|
| 1 | corazón | sin cambios | Ocho bloques son el mínimo para secuencia + ciclo infinito + ciclo anidado. |
| 2 | xilófono | sin cambios | Tres bloques que muestran la cadena entrada → ajuste → salida de un vistazo. |
| 3 | xilófono con LEDs | forma | Invertir los operandos de la suma: las dos salidas quedan con la misma gramática. |
| 4 | visualizador | forma | Ordenar las columnas de micro:bit para que el código siga el orden del dibujo. |
| 5 | robot cosquilloso | sin cambios | El patrón de evento ya está en su forma canónica. |
| 6 | alarma de galletas | forma | Encender y apagar en el mismo orden; tres rótulos en vez de un muro de texto. |
| 7 | despertador | sin cambios | Es el ejemplo canónico del si … si no de toda la secuencia. |
| 8 | murciélago | sin cambios | Lo que parecía repetición son cuatro dibujos distintos: una animación. |
| 9 | desafío del robot | sin cambios | Los comentarios llaman toques a la variable energia. |
| 10 | corazón del robot | forma | Los nombres dicen tamaño y guardan milisegundos. |
| 11 | vela de cumpleaños | forma | flama es un sustantivo haciendo de valor de verdad. |
| 12 | no derrames | reestructuración | Dos ciclos para siempre corriendo a la vez, y una carrera invisible. |
| 13 | interruptor de aplausos | sin cambios | Propuesta descartada: era agregar un bloque que no hace nada (§4). |
| 14 | encendido cinematográfico | un bloque menos | Los nombres de los dos contadores están intercambiados. |
| 15 | papa explosiva | forma | El único comentario está pegado a la línea equivocada. |
| 16 | metrónomo | un bloque con nombre | La idea central del programa es la única cosa sin nombre. |
| 17 | batalla de gritos | reestructuración | Dos ciclos contados que giran en vacío para simular una salida. |
Estos programas ya están escritos en su forma mínima legible. Se documenta el porqué, para que la próxima revisión no vuelva a proponer lo mismo.
Ocho bloques: una secuencia dentro de un ciclo infinito, con un ciclo anidado adentro. Es exactamente el mínimo para expresar las tres ideas que la actividad estrena. Poner las pausas en una variable haría el código más elegante para alguien que ya programa, y más opaco para quien lleva diez minutos.
Tres bloques en cadena lineal: leo cómo está inclinado → lo ajusto → suena → espero un poco. Es la primera vez que el programa recibe algo del mundo, y la forma deja ver la cadena completa entrada → transformación → salida de un vistazo, que es el objetivo declarado. Además estrena tres construcciones nuevas: es la carga máxima razonable para una sesión.
+60 / +1000 es el concepto de la actividad y no está
explicado en las dos plataformas: el comentario de micro:bit sí dice por qué se suma (la inclinación puede ser
negativa y el teclado solo recibe positivos), el de Protobject solo declara el rango. Es un arreglo de
comentario, no de algoritmo.El patrón canónico de evento: preparar el estado de reposo → esperar → reaccionar → volver al reposo. Es la
primera vez en la secuencia que hay dos bloques de nivel superior en vez de un solo
repetir para siempre, y la forma hace visible ese concepto.
El cuerpo del ciclo de animación es letra por letra el mismo de la actividad 1. Eso es deliberado y conviene mantenerlo: los eventos se aprenden por contraste, así que si la animación no cambia, la única novedad que hay que procesar es la estructura de dos sombreros.
Este programa funciona como el ejemplo de referencia del si … si no en toda la secuencia,
y por eso el veredicto es tan firme. Las dos ramas son un espejo exacto: dos acciones cada una, en el mismo
orden, con verbo y anti-verbo emparejados uno a uno.
si (nivel de luz > UMBRAL): si no:
reproducir melodía ←→ detener todos los sonidos
mostrar dibujo ←→ borrar la pantalla
Un estudiante puede tapar una rama con el dedo y predecir la otra. Además la polaridad es la correcta: el
caso interesante —el despertador sonando— está en la rama verdadera, no escondido en el si no, y la
condición es afirmativa en vez de una negación.
A primera vista el cuerpo del si parece cuatro veces el mismo par de bloques, listo para
plegarse con repetir 4 veces —que además está disponible desde la primera actividad—. No lo es:
las cuatro imágenes son distintas. Es una animación de cuatro fotogramas, un destello que crece.
. . . . . . . . . . # . # . # . . . . .
. . . . . . # . # . . # # # . . . # . .
. . # . . . . # . . # # # # # . # # # .
. . . . . . # . # . . # # # . . . # . .
. . . . . . . . . . # . # . # . . . . .
(A) (B) (C) (D)
repetir 4 veces mostraría cuatro veces la misma chispa: parpadeo en vez de destello. Y no hay
pliegue parcial posible, porque los fotogramas avanzan en vez de turnarse.
repetir N veces se usa cuando lo que se repite
es idéntico; cuando cada paso es distinto, escribirlo paso a paso es lo correcto. Saber cuándo no usar
un ciclo es parte de saber usarlo. Además, esta es la primera animación de más de dos fotogramas de la
secuencia: verlos uno debajo del otro hace visible que una animación es una lista de imágenes en el tiempo.La estructura ya separa los tres roles de una variable y los pone cada uno en su sitio: crear
(= 0 al iniciar), modificar (+1 en el evento), comparar y mostrar (en el
ciclo). No hay condiciones infladas, ni pasos fuera de orden, ni bloques muertos.
Lo que sí hay que arreglar son los comentarios, y es grave porque cae justo sobre el concepto que se enseña:
la variable se llama energia, pero los comentarios dicen —verbatim, en las dos
plataformas— «Inicia la variable "toques"…» y «Aumenta en 1 el valor de la variable "toques"».
En la actividad donde se introduce la idea de que una variable es una caja con una etiqueta, la etiqueta tiene
que ser una sola.
El orden dentro del evento —primero invertir, después leer el valor nuevo— es el idioma estándar del
interruptor y cualquier otro orden cambia el comportamiento. Las dos ramas son paralelas de verdad. La negación
estado ← no estado expresa «cambia al contrario» en una sola línea, sin condicional auxiliar.
apagar la pantalla en
al iniciar, para que el estado inicial quedara declarado del todo. Es un bloque que no hace
nada: la pantalla ya arranca apagada en ambas plataformas. Se descarta por el criterio de §4.
El estado inicial se documenta en un comentario, no con un bloque inerte.estado a algo como luzEncendida, que se
leería solo. Se descarta: todo el andamiaje de la actividad está construido sobre esa palabra («variables de
estado») y la actividad 14 reutiliza la misma variable. Solo tendría sentido como cambio conjunto.Ni un bloque agregado, ni uno quitado. Cambia lo que el programa dice, no lo que hace. Son las propuestas de mejor relación entre lo que cuestan y lo que rinden.
El objetivo declarado es «una sola entrada, múltiples salidas», y depende de que se vea el paralelo entre las dos salidas. Hoy están escritas con dos gramáticas distintas: el píxel como centro + desviación, la nota como lectura + número.
Propuesta — un solo bloque tocadorepetir para siempre:
borrar la pantalla // apaga el punto del ciclo anterior
dibujar píxel en:
eje móvil = CENTRO + redondear( leer inclinación ÷ K )
tocar nota:
altura = BASE + leer inclinación // antes: leer inclinación + BASE
esperar 100 ms
÷ K con su redondeo en la
única diferencia entre las dos líneas, que es justo lo que la sección «La División Mágica» quiere que
se note: la pantalla es chica y hay que escalar; el teclado no.Las tres columnas se dibujan en el orden 2, 1, 3 en micro:bit y 3, 4, 5 en
Protobject. Ninguno de los dos órdenes cambia lo que se ve —las tres columnas aparecen en la misma pasada—,
pero el de micro:bit obliga a leer el código saltando.
micro:bit: dibujar columna 2 1 dibujar columna 1 2 dibujar columna 3
El cuerpo del si se lee como una lista plana de cinco órdenes, cuando en realidad son
tres momentos. Y hay una asimetría: Protobject enciende luz→sonido y apaga luz→sonido; micro:bit
enciende sonido→luz pero apaga luz→sonido, así que la correspondencia se cruza.
repetir para siempre: // vigilar la caja sin parar si (inclinación de la tapa > umbral): // ¿alguien levantó la tapa? // 1. ENCENDER la alarma dibujar el icono de alarma ← en micro:bit pasa delante empezar el sonido de sirena // 2. DEJARLA sonando esperar 6 segundos // 3. APAGAR lo que encendimos, en el mismo orden borrar el dibujo de la pantalla detener el sonido
si no obligue a pensar en pares de estados.
Además la luz primero es lo que se verifica primero: en una sala con veinte celulares sonando, la comprobación
real de «¿funcionó mi alarma?» es visual.si —el concepto nuevo de la sesión— carga hoy un comentario de cinco
líneas que explica qué es un condicional, y compite con el bloque justo cuando hay que mirar la condición. Esa
explicación ya está, mejor redactada, en el material. Tres rótulos cortos la reemplazan.Los nombres dicen el tamaño del dibujo y guardan una espera en milisegundos.
latidoGrande y latidoPequeño suenan a «corazón grande» y «corazón chico»; nada en el
nombre dice duración. La prueba de que confunden está en el propio comentario de micro:bit, que se contradice:
dice que «la velocidad de latido aumentará» y explica que eso pasa porque «los tiempos son más largos».
al iniciar el programa: ← arriba: se lee primero // RITMO TRANQUILO: así arranca el corazón establecer pausaLarga a ⟨larga tranquila⟩ // espera entre latido y latido establecer pausaCorta a ⟨corta tranquila⟩ // espera de cada destello repetir para siempre: // 1) EL GOLPE FUERTE mostrar corazón LLENO sonar golpe de latido pausa (ms) pausaLarga sonar golpe de latido // este toque anuncia el temblor // 2) EL TEMBLOR: 4 vueltas × 2 imágenes = 8 destellos repetir 4 veces: mostrar corazón HUECO pausa (ms) pausaCorta mostrar corazón CHICO pausa (ms) pausaCorta cuando el dispositivo queda ⟨gesto TRANQUILO⟩: // los MISMOS dos números del bloque «al iniciar» ...
al iniciar y el
gesto que «devuelve la calma» contienen exactamente los mismos dos números, y ese vínculo no está dicho en
ninguna parte: quien cambie el ritmo de partida y no cambie también el gesto obtiene un programa que «vuelve» a
un ritmo que nunca existió.al iniciar y los dos gestos están en la columna izquierda, uno debajo del otro, y el
repetir para siempre a la derecha. No hay nada que reordenar.
Ojo con esto al revisar, porque induce a error: en el texto extraído el
repetir para siempre aparece primero, y eso no dice nada sobre cómo se lee la pantalla — solo que ese
bloque está unos píxeles más arriba. El orden del archivo no es el orden del lienzo. Ya pasó lo mismo en la 9ª. Si
hay que juzgar la disposición, se mira el lienzo o las coordenadas, no la serialización.
flama es un sustantivo haciendo de valor de verdad, y cae justo sobre el concepto que la
actividad enseña. si flama se lee «si llama»: no hay verbo, no se lee como una afirmación que puede
ser verdadera o falsa. Y establecer flama a (no flama) —el bloque estrella de la actividad— se lee
«establecer llama a no llama», que suena a contradicción.
Síntoma verificable: la ficha necesita un recuadro entero para descifrar qué significa (no flama),
y lo explica caso por caso. Ese recuadro está gastando su energía en el nombre en vez de en el concepto. Hay
además homonimia: la llama que se dibuja y flama que se recuerda son dos cosas
distintas con el mismo nombre.
al iniciar el programa:
establecer velaEncendida a verdadero // la vela nace prendida
cuando se detecta un soplo:
establecer velaEncendida a (no velaEncendida) // el soplo da vuelta el estado
repetir para siempre:
si velaEncendida:
// fotograma 1: la llama tiembla hacia un lado
dibujar la vela // redibujar la vela borra la llama anterior
encender el punto (columna al azar , fila de la llama)
esperar 200 ms
// fotograma 2: la llama vuelve al centro
dibujar la vela // otra vez: borra la llama del fotograma 1
encender el punto (columna CENTRO , fila de la llama)
esperar 200 ms
sino:
borrar la pantalla
flama aparece unas diez veces en la ficha. El renombre obliga a
tocarla, o el material queda incoherente. Roza además la decisión editorial abierta flama/llama:
lo que se propone es cambiar la categoría gramatical (predicado en vez de sustantivo), no elegir entre
las dos palabras — llamaEncendida funciona igual de bien.El único comentario del programa está en el lugar equivocado. El texto «Temporizador con tiempo
inicial aleatorio, valor entre 5 y 15» está enganchado al mientras, pero describe la línea de
arriba. Resultado: el mientras —la construcción que esta actividad estrena— queda sin explicación,
y la línea que sí es aleatoria queda sin anotar.
cuando el botón táctil es tocado: si listo: establecer listo a falso // cierra la puerta: mientras dure la ronda, tocar no hace nada establecer tiempoRestante a (entero aleatorio de 5 a 15) // Temporizador con tiempo inicial aleatorio, valor entre 5 y 15. reproducir sonido de suspenso (de fondo) repetir mientras (tiempoRestante > 0): // nadie sabe cuántas vueltas dará: sigue MIENTRAS quede tiempo añadir -1 a tiempoRestante // este bloque es el que hace que la condición llegue a ser falsa esperar 1 segundo ...
tiempo > 0 se puede leer de dos maneras opuestas —«el
tiempo que llevo jugando» o «el tiempo que me queda»— y solo la segunda explica por qué hace falta un
mientras. Con tiempoRestante > 0 la condición es la explicación. Y el
contraste con repetir N veces, que es lo que esta actividad tiene que enseñar, queda anotado en las
dos líneas donde el ojo se detiene: arriba «el número se sortea», abajo «por eso el ciclo pregunta en vez de
contar».pausado = verdadero significa «no hay nadie jugando», así que cada lectura de
si pausado obliga a dar vuelta la frase mentalmente; y en al iniciar se «pausa» algo
que nunca empezó. Con listo: «si está listo → ciérralo → juega → vuelve a dejarlo listo».tiempo aparece 7 veces en la ficha y hay que tocarlas.
pausado no aparece nunca: ese renombre es gratis.Los nombres de los dos contadores están intercambiados respecto a lo que recorren. La variable llamada
filas se enchufa en la x (que es la columna) y la llamada columnas en la
y. Como el ciclo interior es el que varía más rápido, y el interior mueve la x, la pantalla se llena
renglón por renglón de arriba hacia abajo — pero el código, leído en voz alta, dice lo contrario:
«para cada columna, para cada fila».
En la única lección cuyo objetivo declarado es qué recorre el ciclo de fuera y qué el de dentro, los nombres responden esa pregunta al revés.
Propuestasi estado:
// barrido de encendido: fila por fila, de arriba hacia abajo
contar con fila desde 1 hasta 7:
contar con columna desde 1 hasta 7:
encender píxel x = columna y = fila
esperar 10 ms
encender píxel x = 1 y = 1 ← se elimina: no hace nada
sino:
// el mismo barrido, pero apagando
...
x = columna, y = fila es la convención de
siempre; aprenderla bien aquí no cuesta nada, y aprenderla al revés se paga en cada actividad con cuadrícula.La idea central del programa es lo único que no tiene nombre. El patrón que la ficha explica en prosa —«constantemente calculamos el tiempo que ha pasado»— existe en el código solo como una resta escondida dentro de una comparación. Todo lo demás (bpm, intervalo) sí está en una variable.
Propuestarepetir para siempre: // Sin 'esperar': el ciclo mira el reloj miles de // veces por segundo y casi siempre no hace nada. establecer bpm a (inclinación en x + ajuste) establecer intervaloPulso a (60000 ÷ bpm) // 1 min = 60000 ms; cada pulso dura 60000 ÷ bpm establecer tiempoTranscurrido a (milisegundos − ultimoPulso) si (tiempoTranscurrido > intervaloPulso): sonar el pulso establecer ultimoPulso a milisegundos // reinicia el cronómetro; sin esta línea // sonaría sin parar para siempre
tiempoTranscurrido >
intervaloPulso compara dos duraciones con nombre, en las mismas unidades, sin cálculo intermedio — y
evita el error clásico de leer la comparación como si fuera entre instantes. El reloj no desaparece:
aparece dos veces y ambas en una asignación, que es donde se lee con calma.establecer ultimoPulso a milisegundos conserva su
propia lectura del reloj. Colapsarla en una sola lectura al comienzo del ciclo —que ahorraría un bloque y
se parece más al texto de la ficha— alteraría el tempo, porque en micro:bit el sonido bloquea y esa segunda
lectura ocurre después. Se mantienen dos lecturas, en las mismas posiciones.ultimoPulso —que la ficha llama «el paso más
importante»— no llevan ninguno..hex de micro:bit sigue diciendo
ultimoBeat/intervaloBeat (spanglish), mientras Protobject ya usa
ultimoPulso/intervaloPulso. La decisión ya estaba tomada; nunca llegó al firmware.Los dos únicos casos donde la forma del programa pelea contra la idea que quiere enseñar.
Dos ciclos para siempre corriendo a la vez. El programa se lee de arriba abajo y no se
ejecuta de arriba abajo: los dos ciclos corren simultáneamente y se comunican por variables compartidas. Eso es
concurrencia — un concepto que la progresión no ha enseñado, que la actividad no menciona, y que aquí no aporta
nada. Nadie puede saber, leyendo el código, por qué son dos y no uno.
De regalo trae una carrera invisible: la condición se evalúa con una muestra del sensor y el punto puede dibujarse con otra posterior, así que en el instante justo se puede pintar un punto rojo dentro de la zona verde.
Propuestapara siempre:
# 1) medir: llevar la inclinación a una posición de LED
xDesplazado ← leer inclinación x + DESPL
ledX ← redondear( (xDesplazado × NLEDS) ÷ RANGO )
yDesplazado ← leer inclinación y + DESPL
ledY ← redondear( (yDesplazado × NLEDS) ÷ RANGO )
# 2) decidir: ¿está centrado en cada eje?
centradoX ← (ledX ≥ MIN) y (ledX ≤ MAX)
centradoY ← (ledY ≥ MIN) y (ledY ≤ MAX)
# 3) mostrar y avisar
borrar la pantalla
si (centradoX y centradoY):
dibujar punto en (ledX, ledY) [verde]
si debeSonar:
emitir sonido grave
esperar 100 ms
debeSonar ← falso
si no:
dibujar punto en (ledX, ledY) [rojo]
detener sonido
esperar 100 ms
emitir sonido agudo
debeSonar ← verdadero
si pasa a ser el titular en vez de la letra chica. Hoy la condición es
un monolito de tres y anidados con cuatro comparaciones dentro de la ranura; con
si (centradoX y centradoY) se lee palabra por palabra la frase que la propia ficha enseña. La
lección del operador y no se diluye: se reparte en tres líneas legibles en vez de una ilegible.
Y la tabla de verdad se puede probar apuntando con el dedo — «mantengo el equilibrio izquierda-derecha pero me
inclino adelante»: centradoX verdadero, centradoY falso.inclinacionX ya no contiene
una inclinación: contiene un número de LED. Por eso inclinacionX ≥ 3 se lee mal — parece
hablar de grados y habla de columnas. Y sonidoFijo es el nombre menos útil de la idea más difícil:
lo que significa es «todavía me falta tocar el pitido de acierto». Con debeSonar, el mecanismo de
disparo único se explica solo: «si debe sonar, suena y ya no debe».xDesplazado/yDesplazado, después centradoX/centradoY.
Fundir los ciclos y los dos renombres no cuestan ninguna variable y son lo que más rinde.Hay un «salir del ciclo» disfrazado. Los dos ciclos contados prometen «recorre toda la pantalla», pero
el programa nunca quiere recorrer toda la pantalla: quiere encender una casilla más mientras el grito siga.
Como un ciclo contado no se puede interrumpir, la salida se simula con un si interior que deja el
cuerpo vacío — y cuando el grito para, los ciclos siguen girando sin hacer nada. Control de flujo
invisible: lo peor que se le puede pedir a alguien que recién aprende a leer bloques.
Encima, la misma condición está escrita dos veces (en el mientras y en el si
interior, con el mismo número mágico duplicado), hay seis niveles de anidamiento, y la estructura no refleja la
idea: «medir cuánto dura un grito» es repetir mientras dure una condición. El doble ciclo contado es un
modismo de dibujar, no de medir.
repetir para siempre:
si partidaEnCurso:
// el gritómetro parte en la primera casilla
fijar columna a ⟨primera⟩
fijar fila a ⟨primera⟩
// mientras el grito siga, una casilla más cada medio segundo
repetir mientras (nivel de sonido ≥ 5):
encender el píxel (x = columna, y = fila)
reproducir clip de avance
esperar 500 ms
// avanzar a la casilla siguiente
añadir 1 a columna
si columna > ⟨última⟩:
fijar columna a ⟨primera⟩
añadir 1 a fila
si fila > ⟨última⟩:
fijar fila a ⟨primera⟩
// el grito terminó: resultado y reinicio
reproducir clip final
esperar 5 s
detener el sonido
borrar la pantalla
partidaEnCurso ← falso
repetir mientras (nivel de sonido ≥ 5) se lee literalmente
como el juego: mientras grites, sigue. Desaparece el ciclo que gira en vacío: cada vuelta es una
casilla, verificable a ojo. Queda una sola copia del umbral, así que la pregunta «¿qué valor cambiarías?» tiene
una sola respuesta. Y fila/columna se vuelven visibles como lo que son —la posición
del gritómetro, memoria del juego— en vez de esconderse como índices de iteración. El avance con retorno de
línea es además un patrón nombrable y transferible: sumo 1 a la columna; si me pasé del borde, vuelvo al
principio y bajo una fila, que es el gesto de escribir en un cuaderno.Dos revisiones llegaron a conclusiones opuestas sobre el mismo tipo de bloque, y eso obligó a fijar una regla.
En la actividad 13 se propuso agregar apagar la pantalla en al iniciar,
con el argumento de que el estado inicial quedaba declarado del todo — y justificando que era «puramente de
forma» precisamente porque no tiene efecto: la pantalla ya arranca apagada.
En la actividad 14, en la misma revisión, se propuso quitar un
encender píxel (1,1) muerto, con el argumento de que «una instrucción que no hace nada es lo
peor que se puede dejar delante de alguien que está aprendiendo a predecir qué hace cada bloque».
No pueden valer las dos. El criterio adoptado es el segundo: un bloque inerte enseña que los bloques se ponen para contar algo, no para hacer algo — y eso es exactamente lo contrario de lo que hay que construir. El estado inicial se documenta en un comentario. La propuesta de la 13 queda descartada; la de la 14 se mantiene.
Apareció en siete actividades sin buscarlo, y siempre del mismo modo: el comentario no está donde está el aprendizaje. Un comentario que habla de otra línea enseña que los comentarios no hay que leerlos.
| Actividad | Qué pasa |
|---|---|
| 03 · xilófono LEDs | Dice «utilizando ejes x e y» cuando solo se calcula un eje. Arrastra un error de tipeo: «a una aceptable e una posición». |
| 09 · desafío del robot | Llama toques a la variable, que se llama energia. En las dos plataformas, y en la actividad donde se introduce el concepto de variable. |
| 10 · corazón del robot | Se autocontradice: «la velocidad aumentará» porque «los tiempos son más largos». Y el mismo texto encabeza los dos manejadores, que hacen cosas opuestas. |
| 13 · interruptor | Cuatro erratas en el comentario de la negación, idénticas en ambas plataformas: «transoforma», «varibale», «faslo», «vardadero». |
| 14 · encendido | Los comentarios sostienen la lectura equivocada de los ciclos. En micro:bit están duplicados literalmente en la rama sino, donde además afirman algo falso. |
| 15 · papa explosiva | El único comentario describe la línea de arriba, no aquella a la que está pegado. La construcción que la actividad estrena queda sin explicar. |
| 16 · metrónomo | Habla de «tono» y «frecuencia» sobre un golpe de batería sin altura, y es el único comentario del programa. |
Desajustes entre lo que la ficha afirma y lo que el programa hace. No son parte de la refactorización — se listan porque salieron de ella.
| Actividad | Desajuste |
|---|---|
| 02 · xilófono | La ficha dice «¡usaremos el eje Y!» y luego pregunta «¿qué pasaría si leyera el eje X?» — una pregunta que el código de micro:bit ya tiene respondida, porque ahí lee x. |
| 08 · murciélago | La ficha habla del «vuelo» de un murciélago; los fotogramas son un destello que estalla (el propio comentario del código dice «una animación de una luz»). El fotograma C de micro:bit es además la misma imagen que la actividad 7 usa para el sol. |
| 09 · desafío del robot | El texto dice «cargarla hasta 7», cierto solo en Protobject: en micro:bit se gana con 5 toques. |
| 13 · interruptor | La ficha describe una inicialización que el código no hace («colorea con negro el dibujo LED»). Ojo: el bloque que describe sería además el equivocado — un relleno negro se mapea a DrawImage, no a ClearDisplay. |
| 14 · encendido | La ficha explica el barrido al revés, y la pregunta de reflexión —«¿qué cambiarías para que fuera de arriba hacia abajo?»— pide lo que el programa ya hace. Con los nombres corregidos, vuelve a ser contestable. |
| 16 · metrónomo | Tres nombres distintos para la misma variable: ultimoPulso en la ficha, ultimoTiempo en la guía docente, ultimoLatido en la planificación — y ultimoBeat en el firmware. |
Cuatro fichas nombran explícitamente a otra actividad, lo que va contra la regla del proyecto de que la progresión está en el orden y no en las remisiones textuales:
Diferencias entre las dos versiones que conviven con la equivalencia formal: el
grafo las da por iguales, y sin embargo se ven o se oyen. No es un defecto de la pipeline — es la consecuencia de
reglas que se eligieron a propósito (el color se ignora, las constantes no cuentan, DrawImage es
agnóstico a qué imagen dibuja). Lo que muestran es que la dimensión algorítmica y la sensorial son
separadas: el PDG certifica la primera, y la segunda necesita un ojo que mire el comportamiento.
| Actividad | Divergencia |
|---|---|
| 01 · corazón | Pausa de 10 ms (micro:bit) contra 100 ms — y en MakeCode mostrar LEDs tiene su propio intervalo interno (~400 ms), así que esa pausa casi no influye y la animación va unas cuatro veces más lenta. Rompe la pregunta de reflexión «¿qué pasa si cambias las pausas?». Además el orden de los fotogramas está invertido: Protobject encoge de forma monótona, micro:bit salta. |
| 05 · robot cosquilloso | En Protobject la cara de al iniciar es la misma que la del final, así que el robot «vuelve a la normalidad» como promete la ficha. En micro:bit son distintas: el estado de reposo cambia después del primer aplauso. Consecuencia visible: en Protobject la cara no se mueve durante los primeros 400 ms mientras el sonido ya arrancó. |
| 08 · murciélago | El 4.º fotograma es idéntico al 2.º en Protobject (pulso que crece y vuelve) y una forma nueva en micro:bit. El ciclo dura 400 ms contra 800 ms: el doble. |
| 09 · desafío del robot | Con energía 0, micro:bit calcula una fila fuera de la matriz: la barra tiene 4 niveles visibles contra los 7 de Protobject. |
| 16 · metrónomo | En micro:bit el pulso se reproduce «hasta que termine»: bloquea el ciclo y el periodo real queda en intervalo + duración de la nota. Es decir, la versión micro:bit no respeta la fórmula — exactamente lo contrario de lo que la actividad enseña. |
| 17 · batalla de gritos | El clip por píxel bloquea en MakeCode y no en Protobject, así que el gritómetro avanza a distinta velocidad. Y 25 LEDs contra 49: llenar la pantalla exige ~12,5 s contra ~24,5 s. La dificultad del juego no es la misma. |
ClearDisplay afirma que en despertador y flama la rama de apagado diverge («MakeCode
usa mostrar LEDs en vez de borrar») — verificado contra la extracción vigente: en ambas la
rama de apagado usa borrar la pantalla. Y OnTiltGestureEvent cita como «verificado
verbatim» un Gesture.ScreenUp que ya no aparece: hoy el par es LogoUp/LogoDown.Siete de las diecisiete revisiones, sin coordinarse, llegaron por su cuenta a la misma conclusión: la mejora correcta sería un procedimiento con nombre, y no existe.
En la 10 serviría para escribir el ritmo de partida una sola vez en vez de tres. En la 11, para nombrar «dibujar el fotograma con la llama en la columna X». En la 12 y la 14, para no duplicar la fórmula de escalado y el barrido. En la 15, para bajar tres niveles de sangría. En la 16, para ponerle nombre a «¿ya es hora de sonar?» — que es literalmente el patrón que la actividad enseña. En la 17, para separar el avance de la casilla del control del grito.
Pero no hay ningún nodo de definición ni de llamada a función en la ontología canónica, ni de listas. Y esto no es una restricción de la progresión —no es que lleguen más adelante—: no llegan nunca. Es el techo del vocabulario compartido por las dos plataformas.
Tiene una consecuencia didáctica que vale la pena decir en voz alta y no esconder: en varias actividades la duplicación es inevitable, y conviene tratarla como lo que es. «Esto se repite porque todavía no sabemos darle un nombre a un trozo de programa» es una frase honesta, y prepara el terreno para cuando ese nombre exista.
Este documento no modificó ningún archivo. Las propuestas de §3 son aplicables tal cual y conservan la equivalencia; lo de §6 y §7 son decisiones de diseño que no corresponde tomar aquí.
| Aplicable directo | Las 10 propuestas de §3, siempre que se apliquen en las dos plataformas a la vez. Aplicar un renombre o un reorden en un solo lado sí rompería la equivalencia. |
| Cuesta tocar las fichas | Los renombres de la 11 (flama, ~10 apariciones), la 15 (tiempo, 7) y la 12 (inclinacionX/Y). El resto de renombres no aparece en el texto. |
| Solo a mano en el editor | Todo lo de §5: los comentarios viven dentro de los bloques. |
| Decisión pendiente | Las divergencias de §7 — sobre todo el pulso bloqueante del metrónomo, que contradice lo que la actividad enseña, y las dos caras de reposo distintas del robot cosquilloso. |