Sesión 7 - Módulos y Recursividad¶
1. Módulos y Paquetes en Python¶
1.1 Introducción a los Módulos¶
Un módulo es un archivo que contiene código Python reutilizable:
Ventajas:
Organización del código
Reutilización
Mantenimiento simplificado
Espacios de nombres separados
1.2 Formas de Importación¶
# Importación básica
import math
print(math.sqrt(16)) # 4.0
# Importación específica
from math import sqrt
print(sqrt(16)) # 4.0
# Importación con alias
import math as m
print(m.sqrt(16)) # 4.0
# Importación múltiple
from math import sqrt, pi
print(sqrt(16), pi) # 4.0 3.141592653589793
# Importación total (no recomendada en general)
from math import *
print(sqrt(16), pi) # 4.0 3.141592653589793
1.3 Módulos Estándar Principales¶
Python incluye una amplia biblioteca estándar con numerosos módulos útiles:
Módulo |
Descripción |
Documentación |
|---|---|---|
|
Funciones matemáticas (trigonometría, logaritmos, etc.) |
|
|
Generación de números aleatorios |
|
|
Acceso a tiempo, conversiones y mediciones |
|
|
Interacción con el intérprete de Python |
|
|
Interacción con el sistema operativo y sistema de archivos |
|
|
Manipulación de fechas y horas |
|
|
Codificación y decodificación de datos JSON |
|
|
Expresiones regulares para procesamiento de texto |
|
|
Estructuras de datos especializadas |
|
|
Funciones estadísticas (media, mediana, desviación, etc.) |
|
|
Manejo de rutas de sistema de archivos orientado a objetos |
Para una descripción detallada y ejemplos, consultaremos algunos módulos específicos:
Módulo math - funciones matemáticas
import math
print(f"Pi aproximado: {math.pi}")
print(f"Seno de 30°: {math.sin(math.radians(30))}")
Módulo random - generación de números aleatorios
import random
print(f"Número aleatorio entre 1 y 10: {random.randint(1, 10)}")
print(f"Elemento aleatorio de una lista: {random.choice(['rojo', 'verde', 'azul'])}")
Módulo time - funciones relacionadas con el tiempo
import time
inicio = time.time()
time.sleep(1) # Pausa de 1 segundo
fin = time.time()
print(f"Tiempo transcurrido: {fin - inicio} segundos")
Módulo sys - interacción con el intérprete
import sys
print(f"Argumentos de línea de comando: {sys.argv}")
import sys
print(f"Versión de Python: {sys.version}")
print(f"Ruta de búsqueda de módulos: {sys.path}")
import sys
# sys.exit(0) # Código 0 indica finalización exitosa
# sys.exit(1) # Código diferente de 0 indica error
sys.exit(1) # Descomentar para probar (código 1 indica error)
Recurso global: Para explorar todos los módulos de la biblioteca estándar, consulte la Referencia de la Biblioteca de Python.
1.4 Creación de Módulos Propios¶
Archivo geometria.py:
# geometria.py
def area_rectangulo(base, altura):
return base * altura
def area_triangulo(base, altura):
return (base * altura) / 2
def area_circulo(radio):
import math
return math.pi * radio ** 2
Uso del módulo:
# uso_geometria.py
import geometria
print(f"Área de un rectángulo de 5x3: {geometria.area_rectangulo(5, 3)}")
print(f"Área de un triángulo de base 4 y altura 6: {geometria.area_triangulo(4, 6)}")
print(f"Área de un círculo de radio 2: {geometria.area_circulo(2)}")
"""
Este es un módulo de ejemplo.
Contiene funciones y variables que pueden ser importadas.
"""
def saludar(nombre):
"""Saluda a una persona por su nombre."""
return f"Hola, {nombre}!"
def despedir():
"""Se despide del usuario."""
return "¡Hasta pronto!"
# Variable del módulo
PI = 3.14159
# La construcción if __name__ == "__main__" permite ejecutar código
# solo cuando el archivo se ejecuta directamente, no cuando se importa.
if __name__ == "__main__":
# Este código solo se ejecutará si el archivo se ejecuta directamente
print("Este módulo se está ejecutando directamente")
print(saludar("Usuario"))
print(f"El valor de PI es: {PI}")
else:
# Este código se ejecutará cuando el módulo sea importado
print("El módulo ha sido importado")
1.5 Paquetes¶
Un paquete es una forma de organizar módulos relacionados en una estructura de directorios.
Ejemplo de estructura de paquete:
matematicas/
__init__.py
aritmetica.py
geometria/
__init__.py
figuras_2d.py
figuras_3d.py
El archivo __init__.py es necesario para que Python trate el directorio como un paquete.
Puede estar vacío, pero indica a Python que el directorio debe tratarse como un paquete.
Ejemplo de contenido para los módulos:
# aritmetica.py
def suma(a, b):
return a + b
def resta(a, b):
return a - b
# geometria/figuras_2d.py
import math
def area_circulo(radio):
return math.pi * radio ** 2
def area_rectangulo(base, altura):
return base * altura
Para importar desde un paquete:
from matematicas.aritmetica import suma, resta
from matematicas.geometria.figuras_2d import area_circulo
import matematicas.geometria.figuras_2d as figuras2d
¿Qué se puede hacer con el archivo __init__.py?¶
El archivo __init__.py puede contener código que se ejecutará cuando el paquete sea importado.
Algunos usos comunes para nuestro ejemplo de matemáticas serían:
# Ejemplo de contenido para matematicas/__init__.py:
# 1. Exponer funciones principales directamente desde el paquete
from .aritmetica import suma, resta
from .geometria.figuras_2d import area_circulo, area_rectangulo
# 2. Definir constantes útiles
PI = 3.14159265359
# 3. Controlar qué se importa con "from matematicas import *"
__all__ = ['suma', 'resta', 'area_circulo', 'area_rectangulo', 'PI']
# 4. Información sobre el paquete
__version__ = '1.0.0'
Con el __init__.py anterior, podríamos hacer:
from matematicas import suma, area_circulo, PI
directamente, sin necesidad de importar de los submódulos específicos.
2. Recursividad en Python¶
2.1 Concepto de Recursividad¶
La recursividad es un concepto donde una función se llama a sí misma:
Componentes esenciales:
Caso base: condición que detiene la recursión
Caso recursivo: llamada a la misma función con un problema menor
La recursividad permite simplificar problemas complejos dividiéndolos en problemas más pequeños.
2.2 Ejemplo Clásico: Factorial¶
def factorial(n):
# Caso base
if n == 0 or n == 1:
return 1
# Caso recursivo
else:
return n * factorial(n-1)
# Pruebas
for i in range(6):
print(f"{i}! = {factorial(i)}")
Flujo de ejecución paso a paso con n=4:
factorial(4) → 4 * factorial(3)
factorial(3) → 3 * factorial(2)
factorial(2) → 2 * factorial(1)
factorial(1) → 1 (caso base)
Retornando: 1 → 2*1=2 → 3*2=6 → 4*6=24
2.3 Ejemplo: Secuencia de Fibonacci¶
def fibonacci(n):
# Casos base
if n <= 0:
return 0
elif n == 1:
return 1
# Caso recursivo
else:
return fibonacci(n-1) + fibonacci(n-2)
# Primeros 10 números de Fibonacci
for i in range(10):
print(f"Fibonacci({i}) = {fibonacci(i)}")
2.4 Consideraciones y Limitaciones¶
import sys
print(f"Límite de recursión actual: {sys.getrecursionlimit()}")
sys.setrecursionlimit(2000) # Aumentar el límite
print(f"Nuevo límite de recursión: {sys.getrecursionlimit()}")
Limitaciones importantes:
Python limita la profundidad de recursión (normalmente 1000)
La recursión consume memoria de la pila (stack)
La recursión puede ser ineficiente para ciertos problemas (ej: Fibonacci)
Segunda Hora: Ejercicios Prácticos¶
1. Ejercicios sobre Módulos y Paquetes¶
Ejercicio 1: Uso de Módulos Estándar¶
Crear un script que:
Genere 10 números aleatorios entre 1 y 100
Calcule y muestre estadísticas: mínimo, máximo, promedio, desviación estándar
Utilice los módulos:
random,statisticsymath
Estructura básica:
# Estructura básica para empezar
import random
import statistics
import math
# Generar números aleatorios
# Calcular estadísticas
# Mostrar resultados
Ejercicio 2: Creación de un Módulo¶
Crear un módulo
fisica.pycon funciones para calcular:Velocidad (distancia/tiempo)
Aceleración (cambio de velocidad/tiempo)
Energía cinética (1/2 * masa * velocidad^2)
Crear un script principal que importe y use estas funciones con ejemplos
Ejercicio 3: Creación de un Paquete Simple¶
Crear un paquete llamado
utilscon la siguiente estructura:utils/ ├── __init__.py ├── matematicas.py └── texto.py
En
matematicas.py, implementar funciones para operaciones básicasEn
texto.py, implementar funciones para procesar texto (ej: contar palabras)Crear un script que importe y use funciones de ambos módulos
2. Ejercicios sobre Recursividad¶
Ejercicio 4: Potencia Recursiva¶
Implementar una función recursiva para calcular x^n (sin utilizar el operador **).
def potencia(x, n):
# Completar aquí
pass
# Pruebas
print(potencia(2, 3)) # Debería ser 8
print(potencia(5, 2)) # Debería ser 25
Ejercicio 5: Suma de Lista Recursiva¶
Crear una función recursiva que sume todos los elementos de una lista.
def suma_lista(lista):
# Completar aquí
pass
# Pruebas
print(suma_lista([1, 2, 3, 4, 5])) # Debería ser 15
print(suma_lista([])) # Debería ser 0
Ejercicio 6: Palíndromo Recursivo¶
Crear una función recursiva que verifique si una cadena es un palíndromo.
def es_palindromo(texto):
# Completar aquí
pass
# Pruebas
print(es_palindromo("radar")) # True
print(es_palindromo("python")) # False
Ejercicio 7: Búsqueda Recursiva¶
Implementar una función recursiva que busque un elemento en una lista y devuelva su índice (o -1 si no existe).
def buscar(lista, elemento, indice=0):
# Completar aquí
pass
# Pruebas
print(buscar([1, 4, 7, 2, 5], 7)) # Debería ser 2
print(buscar([1, 4, 7, 2, 5], 9)) # Debería ser -1
Ejercicios Adicionales para Trabajo en Casa¶
1. Ejercicios sobre Módulos y Paquetes¶
Ejercicio A: Calculadora de Tiempo¶
Crear un módulo para convertir entre diferentes unidades de tiempo (segundos, minutos, horas, días) y un programa que lo utilice.
Ejercicio B: Manipulación de Archivos¶
Crear un módulo con funciones para leer, escribir y analizar archivos de texto, luego usarlo para procesar un archivo de ejemplo.
Ejercicio C: Paquete Completo¶
Crear un paquete para simulación robótica simple con la siguiente estructura:
robot_sim/
├── __init__.py
├── movimiento.py # Funciones para calcular movimiento
├── sensores.py # Simulación de lecturas de sensores
└── utils/
├── __init__.py
└── graficos.py # Funciones para visualizar datos
Implementar al menos 2-3 funciones en cada módulo y crear un script principal que demuestre todas las funcionalidades.
2. Ejercicios sobre Recursividad¶
Ejercicio D: MCD Recursivo¶
Implementar el algoritmo de Euclides para encontrar el máximo común divisor recursivamente.
def mcd(a, b):
# Completar aquí
pass
# Pruebas
print(mcd(48, 18)) # Debería ser 6
print(mcd(101, 103)) # Debería ser 1
Ejercicio E: Recorrido Recursivo de Directorios¶
Usar la recursividad para listar todos los archivos en un directorio y sus subdirectorios (usar el módulo os).
def listar_archivos(ruta):
# Completar aquí
pass
# Ejecutar en el directorio actual
archivos = listar_archivos("./")
for archivo in archivos[:5]: # Mostrar solo los primeros 5
print(archivo)
Recursos Adicionales¶
Documentación oficial de Python sobre módulos: https://docs.python.org/3/tutorial/modules.html
Documentación sobre paquetes: https://docs.python.org/3/tutorial/modules.html#packages
Documentación sobre los módulos estándar: https://docs.python.org/3/library/
Visualizador de recursión: https://www.pythontutor.com/
Blog sobre recursividad en Python: https://realpython.com/python-recursion/