1.12. Definición de funciones

En el ejemplo previo de abstracción procedimental se invocó una función del módulo de matemáticas de Python, llamada sqrt, para calcular la raíz cuadrada. En general, podemos ocultar los detalles de cualquier cálculo definiendo una función. La definición de una función requiere un nombre, un grupo de parámetros y un cuerpo. También puede devolver un valor explícitamente. Por ejemplo, la función simple definida a continuación devuelve el cuadrado del valor que se le pasa como parámetro.

>>> def cuadrado(n):
...    return n**2
...
>>> cuadrado(3)
9
>>> cuadrado(cuadrado(3))
81
>>>

La sintaxis para esta definición de función incluye el nombre, cuadrado, y una lista entre paréntesis de parámetros formales. Para esta función, n es el único parámetro formal, lo cual sugiere que cuadrado sólo necesita una pieza de datos para realizar su trabajo. Los detalles, ocultos “dentro de la caja”, simplemente calculan el resultado de n**2 y lo devuelven. Podemos invocar o llamar a la función cuadrado pidiendo al entorno de Python que la evalúe, pasándole un valor de parámetro real, en este caso 3. Tenga en cuenta que la llamada a cuadrado devuelve un entero que a su vez puede pasarse a otra invocación.

Podríamos implementar nuestra propia función de raíz cuadrada usando una técnica bien conocida llamada “Método de Newton”. El Método de Newton para aproximar raíces cuadradas realiza un cálculo iterativo que converge al valor correcto. La ecuación \(estimacionNueva = \frac {1}{2} * (estimacionVieja + \frac {n}{estimacionVieja})\) toma un valor \(n\) y repetidamente estima la raíz cuadrada haciendo que \(estimacionNueva\) sea \(estimacionVieja\) en la iteración subsiguiente. La estimación inicial utilizada aquí es \(\frac {n}{2}\). El Programa 1 muestra una definición de función que acepta un valor \(n\) y devuelve la raíz cuadrada de \(n\) después de hacer 20 estimaciones. Una vez más, los detalles del Método de Newton están ocultos dentro de la definición de la función y el usuario no tiene que saber nada sobre la implementación para usar la función para su finalidad prevista. El Programa 1 también muestra el uso del caracter # como marcador de comentario. Los caracteres que siguen al # en una renglón se ignoran.

Programa 1

def raizCuadrada(n):
    raiz = n/2    #La estimación inicial será 1/2 de n
    for k in range(20):
        raiz = (1/2)*(raiz + (n / raiz))

    return raiz
>>>raizCuadrada(9)
3.0
>>>raizCuadrada(4563)
67.549981495186216
>>>

Autoevaluación

He aquí una autoevaluación que realmente cubre todo lo visto hasta ahora. Puede que usted haya oído hablar del teorema del mono infinito. El teorema dice que un mono golpeando las teclas, al azar y por por una cantidad infinita de tiempo, en un teclado de máquina de escribir casi con completa seguridad escribirá cualquier texto dado como por ejemplo las obras completas de William Shakespeare. Bueno, supongamos que vamos a reemplazar al mono con una función de Python. ¿Cuánto tiempo cree usted que le tomaría a una función de Python generar tan sólo una frase de Shakespeare? La frase que aspiramos generar es: “yo creo que parece una comadreja”.

Usted no querrá ejecutar esto en el navegador, así que abra su entorno de desarrollo de Python favorito. La forma en que vamos a simular esto es escribiendo una función que genere una cadena de 27 caracteres de longitud, mediante la elección aleatoria de cada caracter de entre las 26 letras del alfabeto más el espacio en blanco. Escribiremos otra función que calificará cada cadena generada aleatoriamente mediante su comparación con la cadena objetivo.

Una tercera función llamará repetidamente a las funciones generar y calificar, entonces habremos terminado si el 100% de las letras son correctas. Si las letras no son correctas, generaremos entonces una nueva cadena completa. Para hacer más fácil seguir el progreso de su programa, esta tercera función debe imprimir la mejor secuencia generada hasta el momento y su calificación correspondiente cada 1000 intentos.

Reto de autoevaluación

Vea si puede mejorar el programa de la autoevaluación manteniendo las letras que sean correctas y modificando sólo un carácter en la mejor secuencia hasta el momento. Éste es un tipo de algoritmo en la clase de algoritmos de ‘ascenso de colinas (hill climbing en la literatura en inglés)’, es decir, sólo mantenemos el resultado si es mejor que el anterior.

Next Section - 1.13. Programación orientada a objetos en Python: Definición de clases