5.9. Glosario

función productiva: Función que devuelve un valor de retorno.

valor de retorno: El valor obtenido como resultado de una llamada a una función.

variable temporal: Variable utilizada para almacenar un valor intermedio en un calculo complejo.

código muerto: Parte de un programa que no podrá ejecutarse nunca, a menudo debido a que aparece tras una sentencia de return.

None: Valor especial de Python que devuelven funciones que o bien no tienen sentencia de return o bien tienen una sentencia de return sin argumento.

desarrollo incremental: Un metodo de desarrollo de programas que busca evitar el depurado añadiendo y probando una pequeña cantidad de código en cada paso.

andamiaje: El código que se usa durante el desarrollo del programa pero que no es parte de la versión final.

Anuncios

6.5. Encapsulado y generalización

Por “encapsulado” generalmente se entiende tomar una pieza de código y envolverla en una función, permitiéndole obtener las ventajas de todo aquello para lo que valen las funciones. Hemos visto dos ejemplos de encapsulado, cuando escribimos imprimeParidad en la Sección 4.5 y esDivisible en la Sección 5.4.

Por “generalización” entendemos tomar algo específico, como imprimir los múltiplos de 2, y hacerlo mas general, como imprimir los múltiplos de cualquier entero.

He aquí una función que encapsula el bucle de la sección anterior y la generaliza para imprimir múltiplos de n.
def imprimeMultiplos(n):

   1: i = 1

   2: while i <= 6:

   3:     print n*i, '\t',

   4:     i = i + 1

   5: print

Para encapsular, todo lo que hubimos de hacer fue añadir la primera línea, que declara el nombre de la función y la lista de parametros. Para generalizar, todo lo que tuvimos que hacer fue sustituir el valor 2 por el parametro n.

Si llamamos a esta funcion con el argumento 2, obtenemos la misma salida que antes. Con el argumento 3, la salida es:

   1: 3     6     9     12     15     18

y con argumento 4, la salida es

   1: 4     8     12     16     20     24

A estas alturas es probable que haya adivinado como vamos a imprimir una tabla de multiplicacion: llamaremos a imprimeMultiplos repetidamente con diferentes argumentos. De hecho, podemos a usar otro bucle:

   1: i = 1

   2: while i <= 6:

   3:     imprimeMultiplos(i)

   4:     i = i + 1

Observe hasta que punto este bucle es similar al que hay en el interior de imprimeMultiplos. Todo lo que hicimos fue sustituir la sentencia print por una llamada a una función.

La salida de este programa es una tabla de multiplicación:

   1: 1 2 3 4 5 6

   2: 2 4 6 8 10 12

   3: 3 6 9 12 15 18

   4: 4 8 12 16 20 24

   5: 5 10 15 20 25 30 

   6: 6 12 18 24 30 36

Cadenas

7.1. Un tipo de datos compuesto

Hasta el momento hemos visto tres tipos: int, float, y string. Las cadenas son cuantitativamente diferentes de los otros dos porque están hechas de piezas menores: caracteres.

Los tipos que comprenden piezas menores se llaman tipos de datos compuestos. Dependiendo de que estemos haciendo, podemos querer tratar un tipo compuesto como una única cosa o acceder a sus partes. Esta ambigüedad es útil.

El operador corchete selecciona un carácter suelto de una cadena.

   1: >>> fruta = "banana"

   2: >>> letra = fruta[1]

   3: >>> 

   4: print letra

La expresion fruta[1] selecciona el caracter numero 1 de fruta. La variable letra apunta al resultado. Cuando mostramos letra, nos encontramos con una sorpresa: a

La primera letra de “banana” no es a. A no ser que usted sea un programador.

Por perversas razones, los científicos de la computacion siempre empiezan a contar desde cero. La 0-sima letra (“cerosima”) de “banana” es b. La 1-esima (“unesima”) es a, y la 2-esima (\dosesima”) letra es n.

Si quiera la cerosima letra de una cadena, simplemente pone 0, o cualquier expresión de valor 0, entre los corchetes:

   1: >>> letra = fruta[0]

   2: >>> print letra

   3: b

A la expresion entre corchetes se le llama índice. Un índice identifica a un miembro de un conjunto ordenado, en este caso el conjunto de caracteres de la cadena. El ³ndice indica cual quiere usted, de ahí el nombre. Puede ser cualquier expresión entera.

7.2. Longitud

La función len devuelve el número de caracteres de una cadena:

   1: >>> fruta = "banana"

   2: >>> len(fruta)

   3: 6

Para obtener la última letra de una cadena puede sentirse tentado a probar algo como esto:

   1: longitud = len(fruta)

   2: ultima = fruta[longitud] # ERROR!

Eso no funcionara. Provoca un error en tiempo de ejecucion IndexError:string index out of range. La razon es que no hay una sexta letra en “banana“. Como empezamos a contar por cero, las seis letras estan numeradas del 0 al 5. Para obtener el ultimo caracter tenemos que restar 1 de longitud:

   1: longitud = len(fruta)

   2: ultima = fruta[longitud-1]

De forma alternativa, podemos usar índices negativos, que cuentan hacia atrás desde el final de la cadena. La expresion fruta[-1] nos da la ultima letra. fruta[-2] nos da la penultima, y así.

7.5. Comparación de cadenas

Los operadores de comparación trabajan sobre cadenas. Para ver si dos cadenas son iguales:

   1: if palabra == "banana":

   2: print "S³, no tenemos bananas!"

Otras operaciones de comparacion son utiles para poner palabras en orden alfabético:

   1: if palabra < "banana":

   2:     print "Tu palabra," + palabra + ", va antes de banana."

   3: elif palabra > "banana":

   4:     print "Tu palabra," + palabra + ", va despues de banana."

   5: else:

   6:     print "Sí, no tenemos bananas!"

Sin embargo, deber³a usted ser consciente de que Python no maneja las mayúsculas y minusculas como lo hace la gente. Todas las mayusuculas van antes de la minúsculas. Como resultado de ello:

Tu palabra, Zapato, va antes de banana.

Una forma comun de abordar este problema es convertir las cadenas a un formato estandar, como pueden ser las minusculas, antes de realizar la comparacion.

Un problema mayor es hacer que el programa se de cuenta de que los zapatos no son frutas.

7.6. Las cadenas son inmutables

Es tentador usar el operador [] en el lado izquierdo de una asignación, con la intención de cambiar un carácter en una cadena. Por ejemplo:

   1: saludo = "Hola, mundo"

   2: saludo[0] = 'M' # ERROR!

   3: print saludo

En lugar de presentar la salida Mola, mundo, este codigo presenta el siguiente error en tiempo de ejecucion TypeError: object doesn’t

   1: support item

   2: assignment.

Las cadenas son inmutables, lo que signi¯ca que no puede cambiar una cadena existente. Lo mas que puede hacer es crear una nueva cadena que sea una variacion de la original:

   1: saludo = "Hola, mundo"

   2: nuevoSaludo = 'M' + saludo[1:]

   3: print nuevoSaludo 

Aquí la solución es concatenar una nueva primera letra a una porción de saludo.

Esta operación no tiene efectos sobre la cadena original.

7.9. El módulo “string”

El modulo string contiene funciones útiles para manipular cadenas. Como es habitual, tenemos que importar el modulo antes de poder usarlo:

   1: >>> import string

El modulo string incluye una funcion llamada find que hace lo mismo que la función encuentra que escribimos. Para llamarla debemos especificar el nombre del modulo y el nombre de la funcion por medio de la notacion de punto.

   1: >>> fruta = "banana"

   2: >>> indice = string.find(fruta, 

   3: "a")

   4: >>> print indice

   5: 1

Este ejemplo demuestra uno de los beneficios de los modulos: ayudan a evitar las colisiones entre los nombres de las funciones predefinidas y las definidas por el usuario. Al usar la notacion de punto podríamos especificar que version de find queremos en caso de haberle daddo un nombre en ingles a nuestra funcion.

En realidad, string.find es mas general que nuestra version. Para empezar, puede encontrar subcadenas, no solo caracteres:

   1: >>> string.find("banana", "na")

   2: 2

Además, acepta un argumento adicional que especifica el índice en el que debería comenzar:

   1: >>> string.find("banana", "na", 3)

   2: 4

O puede tomar dos argumentos adicionales que especifican un intervalo de índices:

   1: >>> string.find("sus", "s", 1, 2)

   2: -1

En este ejemplo, la busqueda falla porque la letra s no aparece en el intervalo de índices desde 1 hasta 2 (sin incluir 2).