Apéndice O — Funciones: introducción.

Objetivo. Hacer una descripción básica de las funciones y su uso mediante algunos ejemplos.

O.1 Definición de funciones

  • Las funciones son la primera forma de estructurar un programa de manera modular y hacer que sea más fácil de entender, mantener y reutilizar.

  • Esto nos lleva al paradigma de programación estructurada, junto con las construcciones de control de flujo.

  • Las funciones en Python son bloques de código reutilizables que realizan una tarea específica.

  • Las funciones pueden requerir parámetros de entrada, realizar operaciones y devolver un valor de salida.

  • La sintáxis es la siguiente:

def nombre_de_la_función(parm1, parm2, ...):
    bloque_de_código
    return resultado

Una vez definida la función, es posible ejecutarla (hacer una llamada a la función) como sigue:

nombre_de_la_función(arg1, arg2, ...)

Si existe la declaración return dentro de la función, entonces regresa un resultado el cual puede ser asignado a una variable como sigue:

variable = nombre_de_la_función(arg1, arg2, ...)

Observa que:

  • Cuando se define la función, se definen los parámetros que recibirá, en este caso param1, param2, ...
  • Cuando se ejecuta la función, se pasan los valores arg1, arg2, ..., los cuales son los argumentos de la ejecución y serán sustituidos en los parámetros de la función.
  • El bloque de código de la función y el return deben tener una sangría. La definición de la función termina cuando termina la sangría.

Veamos un ejemplo simple:

def imprimir_saludo():
    saludo = "Hola mundo desde la función 'imprimir_saludo()'"
  • La función anterior lleva por nombre imprimir_saludo, no requiere de párametros y en el bloque de código solo se define una cadena de nombre saludo.

  • Esta función al ejecutarse no proporcionará ningún resultado debido a que no tiene la declaración return, es decir no regresa ningún valor.

Veamos:

imprimir_saludo()

Si intentamos asignar la función a un variable obtendremos lo siguiente:

hola = imprimir_saludo()
print(hola)
None

Observa que la variable hola no está definida y no contiene ningún valor (None).

Modifiquemos la función como sigue:

def imprimir_saludo():
    return "Hola mundo desde la función 'imprimir_saludo()'"

Ahora la función solo contiene la declaración return y lo que regresa es una cadena. Veamos lo que produce esta función:

imprimir_saludo()
"Hola mundo desde la función 'imprimir_saludo()'"

En esta versión, el resultado de ejecutar la función es la cadena que se regresa. Podemos asignarla a una variable e imprimirla como sigue:

hola = imprimir_saludo()
print(hola)
Hola mundo desde la función 'imprimir_saludo()'

Ahora la variable hola ya está definida con la cadena que regresa la función.

Veamos otros ejemplos de funciones.

Ejemplo O.1: Función para calcular el cuadrado de un número.

Escribir una función que calcule y regrese el cuadrado de un número con las siguientes características:

  • el número lo recibe como parámetro;
  • el nombre de la función debe ser squared.
def squared(numero):         # Se recibe como parámetro el 'numero'
    cuadrado = numero ** 2   # Se calcula el cuadrado del 'numero'
    return cuadrado          # Se regresa el resultado
# Se ejecuta la función con el argumento 2
squared(2) 
4
# Se ejecuta la función con el argumento 3 y el resultado se almacena 
# en la variable 'resultado'
resultado = squared(3)
print(resultado)
9

.

Ejemplo O.2: Función para calcular el promedio de dos números.

Escribir una función que calcule el promedio de dos números.

  • Los dos números se reciben como parámetros.
  • La función regresa el valor del promedio.
def promedio(a, b):       # Se reciben dos argumentos 'a' y 'b'
    prom = (a + b) / 2.0  # Se calcula el promedio 
    return prom           # Se regresa el valor del promedio
promedio(5, 6)
5.5

.

Ejemplo O.3: Función para calcular el promedio de varios números.

Escribir una función que calcule el promedio de una secuencia de números que recibe como parámetro.

Dada la secuencia de números \(x_1, x_2, \dots, x_N\), la fórmula para calcular el promedio es:

\[ \bar{X} = \frac{\sum_{i=1}^{N} x_i}{N} \]

Esta fórmula tiene dos partes:

  1. La suma de todos los números de la secuencia: \(\sum_{i=1}^{N} x_i\). Esto requiere de definir una variable para almacenar la suma y recorrer la secuencia para sumar cada elemento. El siguiente pseudocódigo muestra estas acciones: \[ \begin{array}{lcr} \mbox{suma} \leftarrow 0 \\ \mbox{FOR} \;\; i = 1, \; N \\ \;\;\;\; \mbox{suma} \leftarrow \mbox{suma} + x_i \\ \end{array} \]
  2. Un vez que se tiene la suma, se debe dividir entre el número total de elementos de la secuencia para obtener el promedio.

\[ \mbox{promedio} = \frac{\mbox{suma}}{N} \]

En Python, se podría implementar como sigue:

def prom_sec(secuencia):  # Se recibe la 'secuencia' como parámetro
    suma = 0              # Inicializamos la variable 'suma'
    for xi in secuencia:  # Se realiza el ciclo para recorrer la 'secuencia'
        suma += xi        # Sumamos los elementos de la secuencia
    N = len(secuencia)    # Obtenemos N usando la función len()
    prom = suma / N       # Dividimos entre el total de números
    return prom           # Regresamos el valor del promedio

En Python se tienen varios tipos de secuencias como listas, tuplas, conjuntos, etcétera.

Probemos la función con una lista:

prom_sec([1,2,3,4,5])
3.0

Ahora con una tupla:

prom_sec((1,2,3,4,5))
3.0

Generamos una secuencia con la función range():

prom_sec(range(1,6))
3.0

Con un conjunto:

prom_sec({1,2,3,4,5})
3.0

.

Ejemplo O.4: Números de Fibonacci.

Los números de Fibonacci, denotados con \(F_n\), forman una secuencia tal que cada número es la suma de dos números precedentes e inicia con el 0 y el 1. Matemáticamente se escribe como:

\[ \begin{eqnarray} F_0 & = & 0 \\ F_1 & = & 1 \\ F_n & = & F_{n − 1} + F_{n − 2} \;\;\; \text{para} \; n > 1. \end{eqnarray} \] La secuencia es entonces: 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , 55 , 89 , 144 , \(\ldots\)

# La siguiente función calcula la secuencia de Fibonacci
def fib(n):         # Se recibe 'n' como parámetro
    a, b = 0, 1     # Se inicializan 'a' y 'b'
    while a < n:    # Se inicia el ciclo 'while'
        print(a, end=',')  # Se imprime el número de Fibonacci 'a'
        a, b = b, a+b      # Se actualizan 'a' y 'b'

Observa que esta función no regresa ningún valor, solo imprime en pantalla un valor conforme lo calcula.

fib(150) # ejecutamos la función fib con el argumento 150
0,1,1,2,3,5,8,13,21,34,55,89,144,

Le podemos poner otro nombre a la función

Fibonacci = fib

Ejecutar la función usando el nuevo nombre:

Fibonacci(400)
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,

Podemos ver el tipo de la función:

print(type(fib))
print(type(Fibonacci))
<class 'function'>
<class 'function'>

Incluso podemos ver el identificador en memoria de la función:

print(id(fib))
print(id(Fibonacci))
1494287461696
1494287461696

Observamos que se puede ejecutar la función fib() a través de Fibonacci() y que ambos nombres hacen referencia a la misma función.