Buscar este blog

martes, 30 de julio de 2013

Repetición 2

Una instrucción de repetición que se utiliza mucho es for. Esta instrucción es muy parecida a while, pero con una salvedad, y es que la variable que controla el bucle se puede crear, comprobar e incrementar dentro del mismo for.

for(<definición>; <condición>; <incremento>) {
    instruccion1
    instruccion2
    instruccion3
    ...
    instruccionn
}

La instruccón for repite las instrucciones en el cuerpo mientras se cumple una condición (la que se especifica en la parte intermedia del for). Cuando deja de cumplirse esa condición, termina.

La secuencia de ejecución de las partes que aparecen en el código más arriba son las siguientes:

<definición>;

while( <condición> ) {
    instruccion1
    instruccion2
    instruccion3
    ...
    instruccionn

    <incremento>
}

Es decir, primero (1) se realiza la definición, después (2) se comprueba la condición, y si es falsa, se continúa con la primera instrucción después del for; en cambio, si es cierta, (3) se ejecutan las instrucciones que aparecen dentro del for. Justo después, (4) el incremento, y sólo entonces se vuelve al paso 2.

Por ejemplo, el siguiente programa cuenta del 1 al 5.

import std.io;

for (def i = 0; i < 5; ++i) {
    println( i + 1 );
}
Este código se puede escribir también así:

def i = 0;

while( i < 5 ) {
    println( i + 1 );

    ++i;
}

Finalmente, el ejemplo de la tabla de multiplicar quedaría así:


/** @name   tablaMultiplicar
  * @brief  Visualiza la tabla de multiplicar
  * @author jbgarcia@uvigo.es
  * @date   2013-07-30
  */

import std.io;

final def x = 5;

for(def i = 0; i < 10; ++i) {
    print( i + 1 );
    print( " x " );
    print( x );
    print( " = " );
    println( x * ( i + 1 ) );
}

Obteniendo exactamente el mismo resultado que en la anterior entrada.

Repetición

La tercera estructura que veremos en cuanto a los lenguajes procedimentales (como jC), después de la secuencia (las instrucciones se ejecutan una detrás de otra, en el orden en el que fueron escritas), es la repetición (también llamada iteración).

La estructura de repetición simplemente significa que un conjunto de instrucciones se repite un número determinado de veces. Para ello, en jC una de las posibles instrucciones a utilizar es while.

while( <condición> ) {
    instruccion1
    instruccion2
    instruccion3
    ...
    instruccionn
}

La estructura más arriba se denomina bucle, porque "da vueltas" (es decir, itera o repite), mientras se cumpla una condición (la que se especifica en el paréntesis del while). Cuando deja de cumplirse esa condición, termina.

La secuencia de ejecución de las partes que aparecen en el código más arriba son las siguientes:

repetir:
    if( <condición> ) {
        instruccion1
        instruccion2
        instruccion3
        ...
        instruccionn
    }

Es decir, primero (1) se comprueba la condición, y si es falsa, se continúa con la primera instrucción después del while; en cambio, si es cierta, (2) se ejecutan las instrucciones que aparecen dentro del cuerpo del while. Entonces se vuelve al paso 1.

Por ejemplo, el siguiente programa cuenta del 1 al 5.

import std.io;

def i = 0;

while ( i < 5 ) {
    println( i + 1 );

    i = i + 1;
}
Este código se puede pensar también así:

def i = 0;

repetir:
    if( i < 5 ) {
        println( i + 1 );

        i = i + 1;
    }

La instrucción i = i + 1; se lee como "asignarle a i el resultado de sumarle uno a i". Por ejemplo, si el valor de i es uno, entonces primero se ejecuta lo que está a la derecha del =, i + 1, y esa expresión devuelve 2. Finalmente, se le asigna 2 a i, pues la variable i es el destino de la asignación, lo que está a la izquierda del operador de asignación ('='). Como resultado, el valor de i es ahora 2, y se dice que se ha incrementado. Esta instrucción de incremento se puede abreviar como ++i, o como i++, no habiendo diferencia entre ellas.

import std.io;

def i = 0;

while ( i < 5 ) {
    println( i + 1 );

    ++i;
}

Para terminar, como ejemplo, podemos crear un programa que visualice una tabla de multiplicar. Para ello, es necesario ir multiplicando un número dado por los números del 1 al 10. Dada la descripción del problema, podemos pensar fácilmente en la necesidad de un bucle, que cuente desde el 1 hasta el 10.

import std.io;

def i = 0;
final def x = 5;

while ( i < 10 ) {
    print( i + 1 );
    print( " x " );
    print( x );
    print( " = " );
    println( x * ( i + 1 ) );

    ++i;
}

viernes, 12 de julio de 2013

Decisión

Utilizando programación estructurada (la que soporta jC y estamos estudiando aquí), existen tres conceptos que es necesario conocer. Secuencia, Decisión, y Repetición.

La primera ya la hemos visto claramente, se trata tan solo de que cada instrucción se ejecuta una detrás de la otra, en el mismo orden en el que están escritas en el programa.

La estructura de decisión consiste en que, según se cumpla una condición o no, la ejecución continuará por una rama u otra. Para especificar la condición, y las ramas que se puedan ejecutar, jC, como muchos otros lenguajes de programación, utiliza la instrucción if.

if ( <condicion> )
{
    instruccion1;
    instruccion2;
    instruccion3;
    ...
    instruccionn;
} [ else {
    instruccion1;
    instruccion2;
    instruccion3;
    ...
    instruccionn;
} ]

La instrucción if puede llegar a definir dos bloques de instrucciones: el que se sitúa justo detrás de if, y el que aparece a continuación de éste, detrás de la instrucción else. Este segundo bloque de instrucciones es opcional, no es obligatorio (por eso aparece entre corchetes).

De acuerdo, pero... ¿cómo se especifica la condición? En realidad, es muy sencillo: se utilizan los operadores < (menor que), > (mayor que), == (igual a), != (diferente de), <= (menor o igual que) y >= (mayor o igual que). Estos operadores son binarios, es decir, a la izquierda y a la derecha de ellos se acompañan sendos valores. Dado que no tiene mucho sentido comparar dos literales (por ejemplo, 2 < 5 siempre supondrá el mismo resultado), uno de los dos valores debe ser una variable, o al menos, una constante. Todo esto se resume en la siguiente tabla, utilizando una hipotética variable x:

OperadorSignificado
<Menor que: x < 10
>Mayor que: x > 10
==Igual a: x == 10
!=Diferente de: x != 10
<=Menor o igual que: x <= 10
>=Mayor o igual que: x >= 10

Retomando el ejemplo anterior sobre el IMC, sabemos que un índice de masa corporal menor que 20 implica desnutrición, 20 a 25 es normal, 25 a 30 es sobrepreso, 30 a 35 es obesidad leve, 30 a 35 obesidad moderada, y 35 a 40 obesidad mórbida. Así, resumiendo en una tabla:

IMCSignificado
imc < 20Desnutrición
20 <= imc <= 25Normal
25 < imc <= 30Sobrepeso
30 < imc <= 35Obesidad leve
35 < imc <= 40Obesidad moderada
imc > 40Obesidad mórbida

El código anterior es el siguiente:

import std.io;

final def Altura = 1.72;
final def Peso = 92;

def imc = Peso / ( Altura * Altura );

print( "IMC = " );
println( imc );

Podemos pensar fácilmente cómo complementar la información del índice desnudo, con la información de la tabla anterior. La primera es muy sencilla.

if ( imc < 20 ) {
    println( "Desnutrición." );
}

Así mismo, también la última es muy sencilla.

if ( imc > 40 ) {
    println( "Obesidad mórbida." );
}

Y así sucesivamente. El código completo es el siguiente:

/** @name   IMC
  * @brief  Calcula el indice de masa corporal
  * @author jbgarcia@uvigo.es
  * @date   2013-07-11
  */

import std.io;

final def Altura = 1.72;
final def Peso = 92;

def imc = Peso / ( Altura * Altura );

print( "El índice de masa corporal (IMC) es: " );
println( imc );

if ( imc < 20 )
{
 print( "Estás desnutrido!" );
}

if ( imc > 25 ) {
 print( "Tienes sobrepreso." );
}

if ( imc > 30 ) {
 print( "Tienes obesidad leve." );
}

if ( imc > 35 ) {
 print( "Tienes obesidad moderada." );
}

if ( imc > 40 ) {
 print( "Tienes obesidad mórbida." );
}

El problema es que para los valores que se le han dado al programa, sucede que se producen dos salidas:

El índice de masa corporal (IMC) es: 31.09789075175771
Tienes sobrepreso.Tienes obesidad leve.

Efectivamente, no se pueden colocar los if's de manera independiente. Además, estamos comprobando sólo una condición en cada momento. ¡Y ni siquiera podemos indicar que la persona está normal!

Así, al menos parte del problema consiste en las tres condiciones complejas de antes... no podemos poner 20 < imc < 25 dentro de la condición de un if. La única forma de conseguir algo parecido, es subdividir la condición en dos subcondiciones más pequeñas: imc > 20 y imc < 25. La cuestión es: ¿cómo representar esa 'y' que intuitivamente hemos colocado entre ambas condiciones? Pues podemos utilizar juntores lógicos, representados por &&, || y !.

Juntor lógicoSignificado
&&AND (y). Ambas condiciones deben cumplirse. Normal:
imc >= 20 && imc <= 25
||OR (o). Alguna de las dos condiciones debe cumplirse. Necesita reajuste:
imc < 20 || imc > 25
!NOT (no): La condición no debe cumplirse. Desnutrición:
!( imc > 20 )

A la vista de estos descubrimientos, podemos decir, para una persona normal:

if ( imc >= 20 && imc <= 25 ) {
    println( "Es un IMC normal." );
}

Para una persona con sobrepreso:

if ( imc > 25 && imc <= 30 ) {
    println( "El IMC indica sobrepreso." );
}

Las condiciones complejas es mucho más conveniente colocarlas de tal manera que cada subcondición ocupe una sola línea. De esta manera, es mucho más sencillo leerlo.

if ( imc >= 20
  && imc <= 25 )
{
    println( "Es un IMC normal." );
}

if ( imc > 25
  && imc <= 30 )
{
    println( "El IMC indica sobrepreso." );
}

Así, el código completo queda como sigue:


/** @name   IMC
  * @brief  Calcula el indice de masa corporal
  * @author jbgarcia@uvigo.es
  * @date   2013-07-11
  */

import std.io;

def altura = 1.72;
def peso = 92;

def imc = peso / ( altura * altura );

print( "El índice de masa corporal (IMC) es: " );
println( imc );

if ( imc < 20 )
{
 println( "Estás desnutrido!" );
}

if ( imc >= 20
  && imc <= 25)
{
 println( "Normal." );
}

if ( imc > 25
  && imc <= 30 )
{
 println( "Tienes sobrepeso." );
}

if ( imc > 30
  && imc <= 35 )
{
 println( "Tienes obesidad leve." );
}

if ( imc > 35
  && imc <= 40 )
{
 println( "Tienes obesidad moderada." );
}

if ( imc > 40 ) {
 println( "Tienes obesidad mórbida." );
}

Ahora todo funciona bien. Sólo queda una cuestión, y es que todas las condiciones se están comprobando en todos los casos. Por ejemplo, si la persona tiene un IMC menor que 20, ya no tiene sentido comprobar si está entre 20 y 25, o 25 y 30, etc.

Para solucionar esto, se puede emplear la posibilidad else de una estructura if.

if ( imc < 20 )
{
 println( "Estás desnutrido!" );
} else {

 if ( imc >= 20
   && imc <= 25)
 {
  println( "Normal." );
 } else {
 
  if ( imc > 25
    && imc <= 30 )
  {
   println( "Tienes sobrepeso." );
  } else {
  
   if ( imc > 30
     && imc <= 35 )
   {
    println( "Tienes obesidad leve." );
   } else {
   
    if ( imc > 35
      && imc <= 40 )
    {
     println( "Tienes obesidad moderada." );
    } else {
     println( "Tienes obesidad mórbida." );
    }
   }
  }
 }
}
De esta manera, en cuanto se opta por una rama de la decisión, se descartan todas las demás, puesto que en caso de entrar en el primer bloque de código (cuando la condición es verdadera), nunca se entra en el segundo bloque de código (y viceversa). Otra consecuencia es que la última condición ya no es necesario comprobarla, puesto que, cuando se llega al final de la secuencia de decisiones, es imposible que imc no sea mayor que 40.

El código finalmente queda como sigue:


/** @name   IMC
  * @brief  Calcula el indice de masa corporal
  * @author jbgarcia@uvigo.es
  * @date   2013-07-11
  */

import std.io;

def altura = 1.72;
def peso = 92;

def imc = peso / ( altura * altura );

print( "El índice de masa corporal (IMC) es: " );
println( imc );

if ( imc < 20 )
{
 println( "Estás desnutrido!" );
} else {

 if ( imc >= 20
   && imc <= 25)
 {
  println( "Normal." );
 } else {
 
  if ( imc > 25
    && imc <= 30 )
  {
   println( "Tienes sobrepeso." );
  } else {
  
   if ( imc > 30
     && imc <= 35 )
   {
    println( "Tienes obesidad leve." );
   } else {
   
    if ( imc > 35
      && imc <= 40 )
    {
     println( "Tienes obesidad moderada." );
    } else {
     println( "Tienes obesidad mórbida." );
    }
   }
  }
 }
}

jueves, 11 de julio de 2013

Cálculos

La forma de realizar cálculos en jC es muy sencilla. Las fórmulas se traducen casi tal cual, con la única salvedad de encerrar entre paréntesis las subexpresiones. Pero veámoslo.

Un ejemplo sería calcular la edad de un gato en términos humanos. Aunque no se corresponde demasiado con la realidad. se suele decir que un año la vida de un gato corresponde con siete años en la vida de un ser humano. Así, para calcular los años de un gato en términos de una vida humana, sólo sería necesario multiplicar la vida del gato, en años, por siete.

La única dificultad que nos puede surgir para traducir esta fórmula es saber cómo convertir una expresión matemática a jC. Para asignar un valor a una variable, no es necesario asignar ese valor ya calculado, podemos indicar al lenguaje de programación que lo compute. Las cuatro reglas básicas, matemáticamente hablando, se traducen de forma muy intuitiva al lenguaje. También debemos recordar que, cuando queremos indicar que una subexpresión se quiere calcular antes, esta se debe encerrar entre paréntesis. A continuación, veremos una tabla resumen de operadores matemáticos disponibles.

OperadorSignificado
+Sumar: x + 10
-Restar: x - 10
*Multiplicar: x * 10
/Dividir: x / 10


import std.io;

final def Multiplicador = 7;
def edad = 3;

def edadGatuna = edad * Multiplicador;

print( "Edad del gato: " );
println( edadGatuna );

Para el siguiente ejemplo, poniendo en práctica lo que acabamos de descubrir, vamos a trabajar con una calculadora para el IMC (índice de masa corporal). Este es un valor que se calcula a partir de el peso y la altura (de hecho, es tan simple como: peso/altura2). En cuanto a elevar al cuadrado un valor, sólo es necesario recordar que se obtiene el mismo efecto multiplicando el valor dado por sí mismo. Los números reales se expresan separando la parte entera de la decimal mediante un punto. Para lograr esto, el programa en jC es tan sencillo como:


import std.io;

final def Altura = 1.72;
final def Peso = 92;

def imc = Peso / ( Altura * Altura );

print( "IMC = " );
println( imc );

Al finalizar el programa, la variable imc contiene un valor que, aproximadamente, si está por debajo de 20, indica desnutrición, entre 20 y 25 indica normalidad, entre 25 y 30 indica sobrepeso, entre 30 y 35 obsesidad level, entre 35 y 40 obesidad moderada, y a partir de 40, obesidad mórbida.

En este ejemplo se está utilizando el módulo io (entrada/salida) de la librería estándar, que define las funciones, ya preparadas para nuestro uso: print(), que imprime cualquier valor, y println(), que hace lo mismo, además de un salto de línea a continuación. Aunque podríamos escribir, perfectamente, io.print() y similar, las funciones del módulo de entrada y salida son tan comunes que no resulta necesario. Recuérdese, además, que sólo es estrictamente necesario cuando se producen colisiones de nombres, es decir, una función existe con el mismo nombre en más de uno de los módulos que se están usando.

martes, 9 de julio de 2013

La tortuga

Hasta ahora, hemos estado utilizando la tortuga para mostrar algunos conceptos, pero en realidad no sabemos mucho de ella.

Como ya comentamos al comienzo, el módulo de la tortuga está basado en el lenguaje de programación Logo, y este lenguaje está especialmente diseñado para aprender programación. Utilizando la metáfora de la tortuga como un módulo más, podremos aprender a resolver problemas en jC, casi sin darnos cuenta.

Recordemos que la forma de trabajar con la tortuga es girar, avanzar, y, si se desea, retroceder. Para ello se utilizan las siguientes funciones:

  1. turn(x): Es necesario especificar un ángulo x, para que la tortuga apunte en ese ángulo de una circunferencia imaginaria a su alrededor.
  2. turnRight(x): Es necesario especificar un ángulo x, para que la tortuga gire el ángulo dado en el sentido de las agujas del reloj, con respecto al ángulo al que ya apuntaba.
  3. turnLeft(x): Es necesario especificar un ángulo x, para que la tortuga gire el ángulo dado en el sentido contrario al de las agujas del reloj, con respecto al ángulo al que ya apuntaba.
  4. forward(x): Avanza en el ángulo actual, una distancia x que es necesario especificarle.
  5. backward(x): Avanza en el sentido contrario al ángulo actual, una distancia x que es necesario especificarle.

Para explorar en qué consiste esa circunferencia imaginaria, pongamos en práctica lo anterior con el siguiente programa:

import media.gw;
import media.turtle;

final def Distancia = 100;

turtle.forward( Distancia );
turtle.print( "1 - 90º" );
turtle.backward( Distancia );

turtle.turnRight( 90 );
turtle.forward( Distancia );
turtle.print( "2 - 180º" );
turtle.backward( Distancia );

turtle.turnRight( 90 );
turtle.forward( Distancia );
turtle.print( "3 - 270º" );
turtle.backward( Distancia );

turtle.turnRight( 90 );
turtle.forward( Distancia );
turtle.print( "4 - 0º" );
turtle.backward( Distancia );

turtle.circle( Distancia - 20 );
En el programa anterior, la tortuga avanza y retrocede una determinada distancia, gira 90º, vuelve a avanzar y retroceder, vuelve a girar 90º... y así hasta completar los cuatro giros y avances/retrocesos que permiten configurar la circunferencia imaginaria, pintada ahora de manera real.

También se utiliza el método print() del módulo de la tortuga, que visualiza el mensaje de texto que se le pase, en la posición donde se encuentre la tortuga. La función circle() dibuja un círculo con el radio que se le pase, tomando como centro el punto donde se encuentre la tortuga. Es interesante notar que el valor que se le pasa a circle() no es un valor fijo, sino calculado a partir del valor de la Distancia, restándole 20.

Sabiendo esto... ¿cómo se podría dibujar un cuadrado? Se trataría de avanzar la distancia necesaria para completar un lado, girar 90º, volver a avanzar... y así hasta completar los cuatro lados. El código a continuación hace exactamente esto.

import media.gw;
import media.turtle;

final def Distancia = 50;

// Lado 1
turtle.forward( Distancia );

// Lado 2
turtle.turnRight( 90 );
turtle.forward( Distancia );

// Lado 3
turtle.turnRight( 90 );
turtle.forward( Distancia );

// Lado 4
turtle.turnRight( 90 );
turtle.forward( Distancia );

El código es muy sencillito de entender, hace exactamente lo comentado.

Si deseáramos hacer un triángulo equilátero, el programa no sería más complejo (sólo son tres lados), pero si hay que tener en cuenta que es necesario determinar el ángulo a girar, de forma que finalmente los ángulos de los lados de dicho triángulo sean 60º (un triángulo equilátero tiene todos sus ángulos de 60º. Para cualquier triángulo, la suma de los tres ángulos siempre es 180º).

Dado que la tortuga tiene que girar no 60º, sino lo suficiente para que el ángulo que quede sea de 60º, debemos pensar que si giramos, desde la base del triángulo, 60º, entonces la tortuga no estará mirando hacia dentro del triángulo, sino exactamente hacia fuera. Para alcanzar el ángulo deseado, debemos girar 60º más. En total, 120º.

/**
  * @name Triangulo
  * @brief Los triangulos equilateros tienen sus angulos de 60º
  */

import media.gw;
import media.turtle;

final def Distancia = 50;

// Base
turtle.forward( Distancia );

// Lado 1
turtle.turnLeft( 120 );  // Girar hasta formar 60º
turtle.forward( Distancia );

// Lado 2
turtle.turnLeft( 120 );
turtle.forward( Distancia );

Es posible hacer muchas más figuras geométricas, y, en realidad, dibujos de todo tipo... ¡sólo es necesario experimentar!

lunes, 8 de julio de 2013

Variables

Lo contrario de las constantes son las variables. Mientras una constante adopta un valor que se le indica en el momento de crearla, la variable (se le dé o no un valor al inicio) puede cambiar el valor contenido con el paso del tiempo.

Observemos el código de la lección anterior:

import media.gw;
import media.turtle;

// Distancias
final def Distancia = 35;
final def Angulo = 90;

// Escalón inicial
turtle.forward( Distancia );

turtle.turnRight( Angulo );
turtle.forward( Distancia );

// Escalón siguiente
turtle.turnLeft( Angulo );
turtle.forward( Distancia );

turtle.turnRight( Angulo );
turtle.forward( Distancia );

// Escalón siguiente
turtle.turnLeft( Angulo );
turtle.forward( Distancia );

turtle.turnRight( Angulo );
turtle.forward( Distancia );

Podemos modificar Angulo y Distancia, es decir, la caída desde el peldaño superior al inferior, y el tamaño del peldaño, respectivamente. Pero eso sí, hay que tener en cuenta que todos los peldaños son iguales.

El uso de variables nos permitirá, de hecho, conseguir que cada peldaño tenga un ángulo y tamaño diferente. La sintaxis para crear variables es muy parecida a la de creación de constantes, sólo tenemos que eliminar la palabra clave final.

def <variable> = <valor>;

Veamos el código anterior con una ligera modificación:

import media.gw;
import media.turtle;

// Distancias
def distancia = 35;
def angulo = 90;

// Escalón inicial
turtle.forward( distancia );

turtle.turnRight( angulo );
turtle.forward( distancia );

// Escalón siguiente
turtle.turnLeft( angulo );
turtle.forward( distancia );

turtle.turnRight( angulo );
turtle.forward( distancia );

// Escalón siguiente
turtle.turnLeft( angulo );
turtle.forward( distancia );

turtle.turnRight( angulo );
turtle.forward( distancia );

Las variables siempre se crean como las constantes, pero con la inicial en minúscula. Debemos intentar crear estos nombres tan pequeños como sea posible, pero manteniendo a la vez su significado. "angulo" y "distancia" son perfectamente manejables en cuanto a tamaño, y son muy significativos, es decir, describen con precisión cuál es su significado.

Cuando en un momento dado se quiera modificar una variable, sólo es necesario indicar el nombre de dicha variable, el símbolo '=' y a su derecha, el nuevo valor.

<variable> = <valor>;

Dado que los valores de las variables pueden ser modificadas en cualquier momento, es posible crear una pequeña modificación del programa anterior con valores distintos para cada peldaño de la escalera.

import media.gw;
import media.turtle;

// Distancias
def distancia = 35;
def angulo = 90;

// Escalón inicial
turtle.forward( distancia );

turtle.turnRight( angulo );
turtle.forward( distancia );

// Escalón siguiente
angulo = 70;
turtle.turnLeft( angulo );
turtle.forward( distancia );

turtle.turnRight( angulo );
turtle.forward( distancia );

// Escalón siguiente
angulo = 110;
turtle.turnLeft( angulo );
turtle.forward( distancia );

turtle.turnRight( angulo );
turtle.forward( distancia );

Gracias a esta modificación, los dos últimos peldaños son ahora un tanto estrambóticos, uno caído hacia abajo y el otro empinado hacia arriba. Es tan sólo una muestra de lo que se puede hacer. ¡Las posibilidades son infinitas!¿Por qué no experimentar?

miércoles, 3 de julio de 2013

Constantes

Continuamos con la escalera de la lección anterior. Finalmente, habíamos logrado crear una escalera de tres peldaños, usando el módulo de la tortuga. El código, al que llegamos sería similar al siguiente:

import media.gw;
import media.turtle;

// Escalón inicial
turtle.forward( 25 );

turtle.turnRight( 90 );
turtle.forward( 25 );

// Escalón siguiente
turtle.turnLeft( 90 );
turtle.forward( 25 );

turtle.turnRight( 90 );
turtle.forward( 25 );

// Escalón siguiente
turtle.turnLeft( 90 );
turtle.forward( 25 );

turtle.turnRight( 90 );
turtle.forward( 25 );

El código es simple, y está comentado. Gracias a estas dos características, podemos entender perfectamente lo que hacía el programa, pese a que han pasado ya unos días.

Si observamos el código con detenimiento, veremos que se repiten dos valores muy frecuentes: 25 y 90. El primer valor es el tamaño del peldaño (la distancia a recorrer para pintar un peldaño), y el segundo es el ángulo a girar. Este ángulo siempre es 90, gracias a las interesantes propiedades de las escaleras.

Podemos definir unas constantes para estos dos valores. Las constantes son solo nombres para ciertos valores. Esto hace que sea sencillo recordarlos, o al menos más sencillo que utilizar los valores en sí. En segundo lugar, es posible que queramos cambiar estos valores en el futuro, por ejemplo, porque queramos hacer la escalera más grande. En este momento, es complicado hacerlo, puesto que tendríamos que localizar todos los '25' en el código y cambiarlos manualmente.

Así, las constantes se pueden definir utilizando la siguiente sintaxis:

final def <nombre> = <valor>

Por ejemplo, podríamos definir el ángulo como la constante Angulo.

final def Angulo = 90;
Y también podríamos definir la distancia como la constante Distancia.
final def Distancia = 25;
Es importante acostumbrarse a poner los nombres de las constantes con la inicial en mayúscula. El objetivo es distinguirlo de otros nombres, hacer que destaque sobre el resto de alguna manera.

Si analizamos un poco ambas sentencias, veremos que hay dos partículas comunes: final y def. La primera partícula indica que el valor que le vamos a asignar al nombre es un valor que no va a cambiar en el futuro. La segunda partícula indica que estamos realizando una definición. Así, podríamos leer cualquiera de las dos, por ejemplo la primera, como "defino la constante Angulo con un valor final de 90".

Las constantes se ponen al comienzo del código, para que estén disponibles para el resto del programa. Eso sí, seguiremos manteniendo los import's primero. Así, sólo resta sustituir las apariciones de los valores 25 por Distancia, y 90 por Angulo.

import media.gw;
import media.turtle;

// Distancias
final def Distancia = 35;
final def Angulo = 90;

// Escalón inicial
turtle.forward( Distancia );

turtle.turnRight( Angulo );
turtle.forward( Distancia );

// Escalón siguiente
turtle.turnLeft( Angulo );
turtle.forward( Distancia );

turtle.turnRight( Angulo );
turtle.forward( Distancia );

// Escalón siguiente
turtle.turnLeft( Angulo );
turtle.forward( Distancia );

turtle.turnRight( Angulo );
turtle.forward( Distancia );
Y efectivamente, ahora podemos modificar el valor asignado a Distancia, de tal manera que la escalera saldrá más grande o más pequeño. También podemos variar el ángulo, consiguiendo escaleras exóticas, como la que se muestra a continuación.