3er paso: generalizar un algoritmo (final)

Creo no equivocarme al pensar que tanto para Pier como para nosotros el "tránsito" por este 3er paso del Tutorial va a dejar huellas indelebles en nuestra memoria… cuando mencioné desde un principio que iba a implicar un "salto cualitativo" en nuestra capacidad para hacer programas, de que íbamos a abrir un mundo de nuevas posibilidades, no creo haber exagerado.
Al terminar este 3er paso en realidad también se terminará el aporte que desde la geometría se hace al Tutorial: en el 4to y último paso estaremos ocupados en llevar "un poco más allá" lo obtenido, pensando casi con exclusividad en mejorar la interacción de un usuario cualquiera —con o sin conocimientos de programación— con nuestro proyecto… ya hablaremos en profundidad sobre esto cuando llegue el momento.
Pero no nos dispersemos: vamos ya a resolver las metas que nos quedaron pendientes…

Cronometrando a Pier

Empecemos por la meta más simple de resolver (creo) : procurar que Pier dibuje a cualquiera de todos los polígonos regulares en el mismo lapso de tiempo —5 segundos—
Recuerdo que en la página anterior ya te había dejado esta cuestión para que la vayas pensando (incluso te dí una ayudita) ¿Pudiste resolverla? Espero que sí, porque sólo debías pensar algo como esto:

"si el total de n lados debe ser dibujado en 5 segundos, cada lado debe dibujarse en (5 / n) segundos"

No llega a ser siquiera un problema de regla de 3 inversa, porque ya se está dando el valor que debe permanecer constante: 5 segundos (no hubo que multiplicar nada previamente).
algoritmo genérico
Lo que si está presente —como ves en la fórmula— es una relación de proporcionalidad inversa: a mayor cantidad de lados menos tiempo se debe demorar en dibujar cada uno de ellos, y la fórmula matemática que permite cuantificar este tiempo es del tipo y = K/x.

¿Como era anteriormente la relación tiempo de dibujo vs. cantidad de lados del polígono n?
Fácil: tiempo = n x 1 segundoPier se demoraba n segundos en dibujar, bah
A mayor cantidad de lados, mayor demora en el dibujo. El tiempo en cuestión resultaba ser directamente proporcional a la cantidad de lados n del polígono.

Me parece que no queda mucho para hablar sobre la cuestión. Abrí tu último proyecto, hacé los cambios necesarios hasta que tu programa quede como el que ves en la imagen previa… guardalo y probalo para todos los valores de n que se te ocurran. ¡Ah, prestá especial atención a los tiempos de dibujo!

NOTA SOBRE SCRATCH Y LOS TIEMPOS DE EJECUCIÓN

Si sos algo obsesivo/a como yo, seguramente debes haber estado con tu reloj en mano para comprobar si Pier está haciendo su trabajo en el tiempo que le indicamos (5 segundos).
Habrás comprobado con cierta desazón que a medida que los polígonos son de mayor cantidad de lados a Pier le cuesta cada vez más acercarse a la meta que le estamos imponiendo, y de golpe todo este análisis de lo inversamente proporcional y de cómo implementarlo parece estar en tela de juicio, ¿qué está fallando?
Creéme que no es el algoritmo, ni es Pier  el que no sabe qué cálculos hacer.
Antes de que intente una explicación, probá una simple cosa: sacá el bloque de espera por un rato y probá tu programa. En teoría Pier debería dibujar instantáneamente a cualquiera de los polígonos, pero no lo hace ¿por qué?
Aún en la computadora más rápida cualquier instrucción exige un tiempo para ser cumplimentada, y esto es más evidente en la ejecución de programas dentro de Scratch. Dada que la filosofía de trabajo del entorno está pensada para facilitar el aprendizaje, se termina afectando —por decir de alguna manera— la velocidad de ejecución de los programas, que de hecho no son ni siquiera compilados como en otros entornos de programación orientados a la producción. Pero Scratch está pensado para aprender jugando
En la práctica entonces, y aunque no coloquemos un bloque de espera, existirá un tiempo de demora mínimo en la ejecución de cada vuelta del bucle que nos permite dibujar el polígono, tiempo que dependerá entre otras cosas de la velocidad de tu computadora, de cuantos programas tengas abiertos mientras usás Scratch, etc.
Se puede decir entonces que nuestra meta de los 5 segundos se cumplirá con cierta eficacia para valores chicos de n, donde el programa permite hacer efectivo nuestro razonamiento de lo inversamente proporcional, pero a medida que n se haga cada vez más grande no sólo se perderá este comportamiento, sino que también la respuesta del pobre Pier  se volverá tristemente — y pese a sus esfuerzos— de nuevo directamente proporcional a n, ya que como dijimos existirá un tiempo mínimo de demora en la ejecución de cada paso del bucle.
(¿Se entendió algo?… hice lo que pude).
Para cerrar esta cuestión —que te llevó a aprender algo nuevo que deberás tener presente de aquí en más— concluímos: la meta de los 5 segundos es posible de ser alcanzada desde el punto de vista teórico (en el algoritmo), pero en la práctica sólo podrá ser cumplida con cierta eficacia hasta ciertos valores de nlo siento, platónicos abstenerse—.

Hagamos de Pier alguien centrado

O por lo menos que su trabajo sí lo sea, porque ya sabemos de cuán centrados pueden ser los artistas… (chiste).

La meta del centrado

No está de más dejar bien en claro lo siguiente: la meta del centrado de los polígonos tiene que ver estrictamente con las limitaciones que nos impone el entorno (léase el tamaño del escenario), y nada que ver con la eficacia intrínseca que tiene nuestro algoritmo para posibilitar el dibujo de las figuras.
Conseguir un centrado perfecto tanto horizontal como verticalmente para todos los polígonos regulares posibles sería una meta a la que podría llegarse haciendo uso de la trigonometría ("¿tri qué?"), pero prefiero no terminar alejando a los pocos lectores que me quedan… intentaré proponer soluciones más simples que se adecúen lo mejor posible a lo que queremos.
¿Dije soluciones? Si, porque voy a proponer 2 maneras de conseguirlo… dos senderos que se bifurcan (… y ningún jardín, don Jorge Luis  [referencia culta que en algunas de las bifurcaciones del tiempo yo debo estar aclarando, pero en esta no]).

Primer sendero

Cuando nos referimos al centrado horizontal del cuadrado y del pentágono regular en los 2 pasos anteriores de este Tutorial (¡como añoro esos tiempos en que todo era tan simple! ) estabamos en el fondo tratando con un tema de simetría axial respecto al eje y (reguauu!).
Mucho nombre para algo más bien simple y común… si mirás tu cara al espejo en la mañana vas a ver un caso de simetría axial: podés imaginar un eje vertical que divida tu rostro en 2 partes simétricas, y que debería pasar por tu nariz (no en mi caso, lamentablemente).
Una de las cosas que posibilita tal simetría es el hecho de que el primer segmento que es dibujado (¡1er lado, bueno!) es horizontal. Recordá que una de las condiciones iniciales que le instruímos a Pier es que comience a dibujar apuntando en dirección 90º… y esto es lo que hace que el segmento sea horizontal tanto para el cuadrado como para el pentágono —y en realidad para cualquiera de los polígonos posibles de dibujar con nuestro algoritmo genérico (la instrucción de apuntar en dirección 90º sigue estando presente en él, y por tanto afectará a todos)—.
1er pentágono
Si mirás la imagen que acompaña mis palabras te debería resultar más claro: el segmento en cuestión necesita quedar equirrepartido (?) a ambos lados del eje , por tanto las coordenadas de inicio de Pier deberían tener un valor de abcisa de x = -l /2 (siendo l  la longitud de cada lado). Dada la simetría inherente a cualquier polígono regular, esto garantiza el centrado de la figura.
Ya determinamos en la página anterior cuanto es lo que debe moverse Pier para dibujar cada lado [es 800 / n ], por lo que la coordenada x de inicio [si queremos que el polígono quede centrado horizontalmente] debe ser x = -400 / n .
¿Pero que hay del centrado vertical? Conseguir esta meta es mucho más complicado, porque ya habrás observado que el valor de ordenada y = 100  resulta óptimo sólo para el cuadrado, pero a medida que polígono sea de mayor cantidad de lados su dibujo se va "desplazando" hacia abajo, perdiéndose el centrado.
Lamentablemente la única solución posible es ir cambiando el valor de la ordenada inicial en función de n, pero su análisis nos llevaría a necesitar el auxilio de la trigonometría, y pienso que va más allá de los objetivos de este tutorial  (igual después te muestro como quedaría el bloque que le daría a Pier  las coordenadas iniciales).
algoritmo genérico
¿Qué hacer entonces? Yo propongo una solución "de compromiso", que será el dejar un valor fijo para la ordenada igual a y = 127 pasos —que será más que adecuado para polígonos con n grande, y funciona bastante bien ya cuando n > 8—.
Este número 127 no surge mágicamente: del análisis trigonométrico del problema se verifica que a medida que n crece (y el polígono regular se va pareciendo más y más a un círculo) el valor del radio y de la apotema son cada vez más parecidos, y tienden al valor perímetro / 2π
—para los valores de nuestro problema será 800/2π pasos = 127,323... pasos—
Desde ya podés ir probando estos últimos cambios… vas a comprobar que especialmente en el cuadrado y en el hexágono regular el centrado vertical resultante deja bastante que desear, pero bueh.

Lo prometido es deuda…

Te había prometido mostrarte como quedaría el bloque en donde tanto la absisa inicial como la ordenada inicial que le asignamos a Pier están en función de n, y posibilitan el correcto centrado de cualquier polígono que nos propongamos dibujar.
bloque alternativo
NOTA: cuando hablamos del "correcto centrado" nos estamos refiriendo a que el centro del polígono coindida con el centro del escenario.

Cosa rara

En la expresión de la ordenada y  aparece la función trigonométrica tangente [tan(ω)] , en donde el argumento ω se corresponde con la magnitud de un ángulo ( en nuestro caso 180º/n ).
Si sos lo suficientemente osado, probá de "armar" este —mucho más complejo— bloque para reemplazar a aquel —mucho más simple— que usamos en nuestro algoritmo; es interesante que puedas comparar visualmente los resultados obtenidos en cada caso (prestale atención también a las coordenadas de Pier).

Segundo sendero

Mientras estuve pensando en como resolver de la manera más simple todo este tema del centrado de los polígonos, fue evidente que —tal como acabamos de ver— la solución más adecuada distaba de ser simple, y la simple (que es dejar un valor fijo para la ordenada inicial igual a 127 pasos) distaba de conformarme (especialmente para el caso del cuadrado).
¿Tendremos que conformarnos con esta solución de compromiso? ¿No nos estaremos pasando algo por alto?
Si nos remontamos a la definición de las metas para el dibujo del cuadrado (long, long time ago), hay una de ellas —la 2da— que tiene sentido específico únicamente para el cuadrado, y de la cual derivaba que Pier dibujase el primer lado apuntando en dirección 90º. Con el transcurso del Tutorial fuimos "arrastrando" progresivamente los efectos de esa meta hasta que terminó formando parte de nuestro algoritmo genérico…
¿Pero es indispensable que ese primer lado sea horizontal?
Pensemos: si sacamos esta "restricción heredada" la consecuencia será que nuestro problema dejará de estar claramente definido… dicho de otra manera, podrán ser dibujados infinitos polígonos regulares de n lados que queden centrados y con un perímetro de 800 pasos (aunque no dibujados simétricamente respecto a algún eje).

Lo que vamos a hacer es colocar una nueva meta que tenga sentido para cualquier polígono regular, y que —con el fin de simplificar el problema del centrado— también se basará en una simetría axial respecto al eje y.

("¿Pero no es lo que usamos antes, de qué segundo sendero me estás hablando?") . Tomate un segundo para pensar si no habrá otra manera de tener la simetría que estamos proponiendo.
2do pentágono
Como ves en la figura, existe una segunda manera de conseguir simetría axial respecto al eje y —comparala con la imagen de un poco más arriba—
Es bueno aclarar que estamos usando como ejemplo a nuestro ya conocido pentágono regular, pero las conclusiones a las que arribemos pueden hacerse extensivas para cualquier otro polígono regular (lo dejo por tu cuenta, ¡pensá!).

¿Qué ventajas tiene esta solución?

Hay una que es evidente: el valor de la abcisa de inicio que necesitamos será siempre x = 0   (si, para cualquier polígono regular). Con esto sólo ya se garantiza el centrado horizontal —para nuestro caso de polígonos regulares con simetría axial—.
En cuanto al valor de la ordenada inicial, en principio caeríamos en otra cuestión de dependencia trigonométrica respecto al valor que le asignemos a n —cuestión en la cual no nos vamos a adentrar—. Sin embargo ahora usar un valor fijo de y = 127  funciona mucho mejor que para el caso anterior (el cuadrado sigue teniendo algún desvío apreciable respecto del centrado vertical, pero los resultados generales son más que aceptables).
Pero no todo es color de rosa: deberemos reemplazar la condición apuntar en dirección 90º por otra más compleja (a mirar la imagen). En la misma se aprecia que por razones de simetría nuestro primer segmento estará girado en  γ /2 = 180º / n  respecto de los 90º originales —si no recordás de dónde salen estos valores angulares, volvé a mirar este análisis geométrico—.
algoritmo genérico 2
Concluímos de todo lo anterior que si seguimos este "sendero" Pier deberá posicionarse paradito en las coordenadas (x= 0; y= 127) pero ahora apuntando a la dirección 90º+ 180º/n… quizás nuestro algoritmo no gane en simplicidad, pero los polígonos que con él podremos dibujar quedarán más centrados.
Ya tenés a la vista el nuevo algoritmo listo para ser probado: desde ya te conviene si o sí trabajarlo como un proyecto separado del anterior, porque al cambiar las coordenadas y la dirección adonde Pier  apunta inicialmente también cambiarán las posiciones de los polígonos dibujados… y al tener 2 proyectos podrás así comparar los resultados obtenidos al final de cada uno de los senderos que seguimos.

Si estuviste atento al analizar el nuevo algoritmo, habrás observado que falta el bloque fijar (n) a (?)   ¿Habrá sido sólo un descuido de este humilde servidor, o se ocultará alguna cuestión detrás de esto?

Pensando en el usuario

Como de seguro estás metido en la piel de un [futuro] avezado programador quizás no te hayas hecho algunas preguntas con la perspectiva de un usuario de tu programa… —de hecho este tópico será el núcleo de lo que trabajaremos en el paso siguiente del Tutorial
¿Te preguntaste como haría un usuario para determinar cuál de todos los polígonos dibujar?
"¡Fácil!", podrías contestar: "va al bloquecito fijar (n) a ( ) y coloca allí el número que corresponde a la cantidad de lados del polígono regular que desea que Pier dibuje".
Por lo visto estás presuponiendo varias cosas, te menciono un par de ellas:
  • que el usuario sabe de algoritmos y programación, y no le molesta ponerse a analizar nuestro proyecto (y que tiene tiempo para hacerlo)
  • que el usuario tiene Scratch instalado y puede así acceder al bloque mencionado (¿sino cómo cambiar el algoritmo?)
    Nota feb 2014: esto en realidad es posible de hacer con Scratch 2.0
Recordá que un usuario puede ver y usar un proyecto si éste ha sido subido al sitio web de Scratch —tal como yo estoy subiendo proyectos vinculado a los Tutoriales ¿lo sabías?—, y lo puede hacer aunque no tenga Scratch instalado en su compu.
Pero (¿por ahora?) no puede ver y/o cambiar la programación presente en el proyecto a menos que lo baje a su compu y si tenga instalado Scratch 1.4 , —esto posiblemente cambie con la introducción de Scratch 2
Nota feb 2014: esto en realidad es posible de hacer con Scratch 2.0
ir a modo presentación
Para ponerse en el papel de un usuario (del tipo que sea) no hay nada más conveniente que usar la Vista en Modo Presentación de Scratch —no recuerdo si hablé de esto en el Tutorial anterior, pero de cualquier manera no está de más traerlo a la luz en este momento—

Modos de ver

Resumiéndolo al máximo, en Scratch 1.4 tenemos 3 modos de visualización: dos de los mismos están orientados al uso por parte de un programador, y el tercero (que es el que nos ocupa) está pensado para ver "aquello que conseguimos hacer" con nuestro programa… es donde vemos el producto final de nuestro trabajo.
Al ser seleccionado este modo sólo podremos interactuar con el proyecto usando los botones de arranque y parada y — si está previsto por nuestro programa— también podremos hacerlo con el teclado, mouse, micrófono y usando los monitores de las variables con el modo deslizador habilitado —si no sabés de que hablo, podés asesorarte aquí—.

Es pensando en el usuario que deberemos cambiar el modo de mostrar el monitor de nuestra variable en pantalla: vamos a usar la opción deslizador.

Una cosa importante a acotar: para que el control a través del monitor sea efectivo, deberá ser retirado del programa el bloque fijar (n) a ( ), ya que de lo contrario terminaría "sobreescribiendo" cualquier valor que desde el deslizador le asignásemos a n.
Resumiendo en pocas palabras: el hecho de asignarle la opción deslizador al monitor de nuestra única variable n les permitirá a los usuarios del programa elegir cual de todos los posibles polígonos regulares dibujar¿todos dije? (¡no termino más!)
monitor: deslizador
Si mirás nuestra última imagen, se evidencia que cuando hacemos clic derecho sobre el monitor de la variable nos aparecerá (dentro del ya conocido menú desplegable) la opción elegir min y max del deslizador: analicemos sus implicancias…
Si bien en un contenedor de valores numéricos en principio no habría restricciones sobre el valor a ser contenido, del análisis de cada problema en particular puede inferirse que algunos valores tendrán sentido para dicho problema y otros no.
dar rango a variable
Para nuestro problema en particular, al no existir polígonos (sean regulares o no) de menos de tres lados, resultará evidente que el mínimo valor que puede tomar n es el de 3.
En cuanto al valor máximo podría ser tan grande como querramos. Yo elegí 20 por una sencilla razón: si el rango es muy grande se hace muy difícil colocar el valor de n usando el deslizador (¡probalo y me contás!)

Un final a toda pompa

La verdad que esto de la bifurcación en dos senderos de nuestras posibles soluciones al problema del centrado lo dejaron a Pier medio confundido —espero que a vos no—, pero lo que lo entusiasmó realmente mucho es el poder llegar a interactuar directamente con el usuario, sin necesidad de tenernos a nosotros de mediadores (ya sabemos como le gusta el protagonismo a nuestro amigo…).
Empezamos este tercer paso imponiéndonos el objetivo de generar un algoritmo génerico para dibujar cualquier polígono regular… y terminamos consiguiendo dos. También pudimos (no sin poco trabajo) mantener casi todas las metas iniciales, e incluso agregamos alguna más: realmente queda una sola cosa por decir a todo esto…
Felicitémonos por todo este esfuerzo: terminamos nuestro 3er paso de este Tutorial (¡dale aire a Pier, que está casi desfalleciente de la emoción!)

PARA VER

En esta circunstancia en particular nos quedaron 2 proyectos nuevos en el sitio web oficial de Scratch: podés visitar esta página para ver la solución que quedó al seguir el 1er "sendero", y esta página muestra como funciona el algoritmo genérico al seguir el 2do "sendero" [recordá que podrás descargarlos a tu computadora sólo si estás suscripto como usuario del sitio, pero la versión online de Scratch 2.0 te permitirá ver la programación].
El principal objetivo a alcanzar en este Tutorial quedó cubierto ya al terminar este 3er paso… nos quedará en el 4to extender y mejorar la presentación de nuestro proyecto ante los ojos de quienes quieran utilizarlo (usuarios que les dicen).
Lo veo a Pier descansando —ahora si relajado—, ojos entrecerrados, sonrisa omnipresente, listo para dormir el sueño de los justos¡justo era lo que iba a recomendarte y recomendarme! Regalémonos todos un merecido descanso… nos vemos en el 4to paso.
Última actualización: Febrero 25, 2014

No hay comentarios.:

Publicar un comentario

© Scratch CodeLab | D153ñ0 b454d0 3n l4 pl4n71ll4 SimpleRWD d3 Oloblogger