Escribir código iterativamente

Muchas veces al programar nos enfrascamos demasiado en la inicialización de variables, uso de estructuras, etc. y perdemos la noción de lo que estamos haciendo realmente, llegando incluso a programar funciones que no hacen lo que queremos ni de lejos.

Una buena idea es escribir en varias fases, de forma iterativa, escribiendo primero el flujo general del programa, y a partir de ahí ir perfilándolo por partes, progresivamente, en vez de intentar hacerlo todo de una vez. Si es necesario, se puede empezar con comentarios.

Supongamos que queremos pasar un texto a mayúsculas. ¿Qué datos de entrada y salida queremos? Básicamente, queremos pasar un texto como entrada y que nos salga convertido todo a mayúsculas, lo que se traduce como:

string pasar_a_mayusculas(string texto);

Vale, ya tenemos lista la interfaz de la función. Lo siguiente es preguntarnos cómo se pasa un texto entero de mayúsculas a minúsculas: pasando a mayúsculas cada uno de sus caracteres:

string pasar_a_mayusculas(string texto) {
    // leer cada letra y pasarla a mayúsculas
    }

Vamos avanzando. Ahora describamos la última tarea:

string pasar_a_mayusculas(string texto) {
    // leer cada letra y pasarla a mayúsculas
    for (i=0; i<n_letras; i++) {
        texto[i] = pasar_letra_a_mayusculas(texto[i]);
        }
    return texto;
    }

char pasar_letra_a_mayusculas(char letra) {
    letra += SEPARACION_MINUS_MAYUS;
    return letra;
    }

La distancia entre mayúsculas y minúsculas es simplemente (A-a), o (Z-z), etc.:

char pasar_letra_a_mayusculas(char letra) {
    int const SEPARACION_MINUS_MAYUS = 'A'-'a';
    letra += SEPARACION_MINUS_MAYUS;
    return letra;
    }

Si lo probamos con el texto “Los programadores.”, obtenemos “,OS PROGRAMADORES(corcheas)”. Vaya, nos hemos equivocado en algo, pero no pasa nada. Tenemos que convertir a mayúsculas sólo lo que sean letras minúsculas y dejar intacto el resto de caracteres.:

char pasar_letra_a_mayusculas(char letra) {
    int const SEPARACION_MINUS_MAYUS = 'A'-'a';
    if // letra es una letra minúscula
        letra += SEPARACION_MINUS_MAYUS;
    return letra;
    }

Vale, tenemos montado un lío de nombres, vamos a renombrar nuestras funciones para hacerlo todo más claro:

char pasar_caracter_a_mayusculas(char caracter) {
    int const SEPARACION_MINUS_MAYUS = 'A'-'a';
    if // caracter es una letra minúscula
        caracter += SEPARACION_MINUS_MAYUS;
    return caracter;
    }

string pasar_texto_a_mayusculas(string texto) {
    // leer cada caracter y pasarlo a mayúsculas
    for (int i=0; i<texto.length(); i++) {
        texto[i] = pasar_caracter_a_mayusculas(texto[i]);
        }
    return texto;
    }

Vale, ahora se entiende mejor. Nuestro siguiente objetivo consiste en averiguar si el caracter es una letra minúscula. Eso quiere decir que está entre ‘a’ y ‘z’:

char pasar_caracter_a_mayusculas(char caracter) {
    int const SEPARACION_MINUS_MAYUS = 'A'-'a';
    if (caracter >= 'a' && caracter <= 'z')  // caracter es una letra minúscula
        caracter += SEPARACION_MINUS_MAYUS;
    return caracter;
    }

Parece que ya está. Lo probamos de nuevo y sale “LOS PROGRAMADORES.” ¡Bingo!

Con este ejemplo se pretende (de)mostrar cómo seguir un proceso iterativo y separar las tareas grandes en otras más pequeñas ayuda a no perder la visión general de qué es lo que se está haciendo y dejar un código más limpio, elegante y legible.

Es importante señalar que, a lo largo del desarrollo del programa nos hemos equivocado (se ha equivocado el autor). No pasa nada: como lo hemos desarrollado por partes, hemos descubierto rápidamente dónde estaba el error, que hemos corregido con una simple linea.

Leave a Reply

Your email address will not be published. Required fields are marked *