Portada de libro electrónico gratuitaPython desde cero con mini-retos: aprende programando (sin teoría eterna)

Python desde cero con mini-retos: aprende programando (sin teoría eterna)

Nuevo curso

12 páginas

Funciones para modularidad, reutilización y pruebas rápidas

Capítulo 5

Tiempo estimado de lectura: 6 minutos

+ Ejercicio

Qué es una función y por qué te cambia el juego

Una función es un bloque de código con nombre que encapsula una tarea. La idea es simple: en vez de copiar y pegar lógica por todo tu programa, la metes en una función y la llamas cuando la necesites. Esto mejora tres cosas clave: modularidad (separar el problema en piezas), reutilización (usar la misma pieza muchas veces) y pruebas rápidas (verificar una pieza aislada sin ejecutar todo el programa).

Cuándo conviene crear una función

  • Cuando repites 3+ líneas de lógica en más de un lugar.
  • Cuando una parte del programa se puede describir con un verbo: calcular, validar, formatear, convertir, resumir.
  • Cuando quieres probar una parte sin depender de entradas/salidas (por ejemplo, sin pedir datos al usuario ni imprimir).

La regla de oro: funciones “puras” para probar más rápido

Para pruebas rápidas, intenta que tus funciones sean lo más “puras” posible: que reciban datos por parámetros y devuelvan un resultado con return, sin leer input ni imprimir dentro. Así puedes llamarlas con distintos valores y verificar resultados en segundos.

def precio_con_iva(precio, iva=0.21):
    return precio * (1 + iva)

print(precio_con_iva(100))      # 121.0
print(precio_con_iva(100, 0.1)) # 110.0

Parámetros vs argumentos (en práctica)

  • Parámetros: variables que declaras en la función (precio, iva).
  • Argumentos: valores reales al llamar (100, 0.1).

Mini-reto 1: extrae lógica repetida a una función

Objetivo: tomar un cálculo que usarías varias veces y convertirlo en función reutilizable.

Paso a paso

  • Identifica una operación que se repite (por ejemplo: aplicar descuento).
  • Define una función con parámetros claros.
  • Devuelve el resultado con return.
  • Úsala en 3 casos distintos para comprobar que sirve.
def aplicar_descuento(precio, porcentaje):
    return precio * (1 - porcentaje / 100)

# Pruebas rápidas (casos típicos)
print(aplicar_descuento(200, 10))  # 180.0
print(aplicar_descuento(50, 0))    # 50.0
print(aplicar_descuento(80, 25))   # 60.0

Mejora opcional: redondeo controlado

def aplicar_descuento(precio, porcentaje, decimales=2):
    resultado = precio * (1 - porcentaje / 100)
    return round(resultado, decimales)

print(aplicar_descuento(199.99, 15))

Diseño de funciones: una responsabilidad, nombre claro

Una función debería hacer una cosa principal. Si tu función empieza a “hacer de todo”, se vuelve difícil de reutilizar y de probar. Un truco: si al describirla usas “y” muchas veces, probablemente debas dividirla.

Ejemplo: separar cálculo de presentación

En vez de mezclar cálculo con texto, crea una función que calcule y otra que formatee.

Continúa en nuestra aplicación.

Podrás escuchar el audiolibro con la pantalla apagada, recibir un certificado gratuito para este curso y además tener acceso a otros 5.000 cursos online gratuitos.

O continúa leyendo más abajo...
Download App

Descargar la aplicación

def total_con_impuesto(subtotal, impuesto):
    return subtotal * (1 + impuesto)

def formatear_moneda(valor, simbolo="$"):
    return f"{simbolo}{valor:.2f}"

total = total_con_impuesto(100, 0.21)
print(formatear_moneda(total))

Return: cómo devolver uno o varios resultados

return termina la función y devuelve un valor. Si necesitas devolver varios datos, puedes devolver una tupla (varios valores separados por comas).

def estadisticas_basicas(numeros):
    minimo = min(numeros)
    maximo = max(numeros)
    promedio = sum(numeros) / len(numeros)
    return minimo, maximo, promedio

mn, mx, prom = estadisticas_basicas([10, 20, 30])
print(mn, mx, prom)

Argumentos por defecto y argumentos con nombre

Los valores por defecto te permiten simplificar llamadas comunes. Los argumentos con nombre hacen la llamada más legible y evitan errores de orden.

def enviar_alerta(mensaje, nivel="INFO", canal="email"):
    return f"[{nivel}] ({canal}) {mensaje}"

print(enviar_alerta("Todo ok"))
print(enviar_alerta("Algo falló", nivel="ERROR"))
print(enviar_alerta("Revisar", canal="slack", nivel="WARN"))

Regla práctica

  • Usa posicionales para lo obvio y corto.
  • Usa con nombre cuando hay 3+ parámetros o cuando el significado no es evidente.

Funciones y alcance (scope): evita variables “mágicas”

Las variables creadas dentro de una función viven ahí (son locales). Evita depender de variables externas “por comodidad”, porque dificulta pruebas y genera errores sutiles. Pasa lo necesario como parámetro.

tasa = 0.21

def mal_total(precio):
    # Depende de una variable externa: difícil de probar y mantener
    return precio * (1 + tasa)

def buen_total(precio, tasa):
    return precio * (1 + tasa)

print(buen_total(100, 0.21))

Mini-reto 2: crea una “caja de herramientas” de funciones

Objetivo: construir un conjunto pequeño de funciones útiles y probables de reutilizar en futuros mini-proyectos.

Paso a paso

  • Crea 3 funciones pequeñas: una de conversión, una de formateo y una de cálculo.
  • Asegúrate de que ninguna imprima: solo devuelven valores.
  • Escribe 2 pruebas rápidas por función (llamadas con print para ver el resultado).
def celsius_a_fahrenheit(c):
    return (c * 9/5) + 32

def recortar_texto(texto, max_len=10):
    if len(texto) <= max_len:
        return texto
    return texto[:max_len-3] + "..."

def area_rectangulo(ancho, alto):
    return ancho * alto

# Pruebas rápidas
print(celsius_a_fahrenheit(0))
print(celsius_a_fahrenheit(30))

print(recortar_texto("hola"))
print(recortar_texto("esto es un texto largo", 12))

print(area_rectangulo(3, 4))
print(area_rectangulo(10, 2))

Pruebas rápidas sin librerías: asserts como “alarmas”

Una forma simple de probar es usar assert. Si la condición no se cumple, Python lanza un error y te avisa exactamente qué caso falló. Es ideal para validar tu lógica mientras programas.

def es_par(n):
    return n % 2 == 0

assert es_par(2) == True
assert es_par(3) == False

def aplicar_iva(precio, iva=0.21):
    return round(precio * (1 + iva), 2)

assert aplicar_iva(100) == 121.00
assert aplicar_iva(10, 0.1) == 11.00

Consejo práctico

  • Escribe 2–5 assert por función: un caso típico, un borde (0, vacío, mínimo), y uno “raro” pero posible.

Mini-reto 3: refactor + pruebas en 10 minutos

Objetivo: tomar un bloque de lógica y convertirlo en funciones testeables con assert.

Paso a paso

  • Crea una función normalizar_nombre que reciba un texto y devuelva una versión “limpia”.
  • Crea una función generar_usuario que use la anterior y devuelva un nombre de usuario.
  • Escribe al menos 4 assert para cubrir casos.
def normalizar_nombre(nombre):
    nombre = nombre.strip().lower()
    # Reemplazos simples (sin meternos en temas avanzados)
    nombre = nombre.replace(" ", "")
    return nombre

def generar_usuario(nombre, anio):
    base = normalizar_nombre(nombre)
    return f"{base}{anio}"

assert normalizar_nombre(" Ana ") == "ana"
assert normalizar_nombre("Juan Perez") == "juanperez"
assert generar_usuario(" Ana ", 2026) == "ana2026"
assert generar_usuario("Juan Perez", 1999) == "juanperez1999"

Checklist de calidad para tus funciones

  • Nombre claro: describe acción y resultado (calcular_total, formatear_moneda).
  • Entradas explícitas: todo lo que necesita llega por parámetros.
  • Salida consistente: siempre devuelve el mismo tipo de dato.
  • Sin efectos secundarios (cuando puedas): no imprime, no modifica cosas externas.
  • Probada: tiene assert o llamadas de verificación con casos variados.

Ahora responde el ejercicio sobre el contenido:

Para facilitar pruebas rápidas de una función, ¿qué característica es la más recomendable según las buenas prácticas del curso?

¡Tienes razón! Felicitaciones, ahora pasa a la página siguiente.

¡Tú error! Inténtalo de nuevo.

Las funciones más fáciles de probar son las puras: reciben entradas por parámetros y devuelven una salida con return, evitando input y print dentro. Así puedes validar casos rápido con llamadas o assert.

Siguiente capítulo

Listas para colecciones y gestión de información

Arrow Right Icon
Descarga la aplicación para obtener una certificación gratuita y escuchar cursos en segundo plano, incluso con la pantalla apagada.