Implementa una búsqueda de libros por título y ejecuta el préstamo con control de errores en Python. Con un módulo Data que centraliza listas de libros y estudiantes, y clases como Biblioteca, Usuario y Estudiante, el flujo valida disponibilidad, muestra mensajes claros y usa excepciones como LibroNoDisponibleError para una experiencia robusta.
¿Cómo preparar Data, Biblioteca y main para la búsqueda?
Para probar con datos realistas, se creó un módulo Data con diez libros y diez estudiantes en listas. Se importan en el archivo principal y se eliminan los elementos previos, manteniendo solo el profesor. Al ejecutar en terminal con python main.py, primero se valida el usuario por cédula y luego se solicitará el título del libro.
¿Cómo se integra Data en main.py?
Importa listas de libros y estudiantes desde Data.
Reemplaza los datos locales: deja solo el profesor y borra libros previos.
Asigna las listas importadas a las variables usadas en main.
Ejecuta en terminal: python main.py.
¿Qué entradas solicita el sistema?
Cédula del usuario para identificarlo por “Buscar Usuario”.
Título del libro con input: "Digite el título del libro".
¿Cómo buscar el libro por título y validar disponibilidad?
Dentro de Biblioteca, se implementa el método buscarolibro que recibe el título, recorre self.libros y retorna el libro si coincide el título y está disponible. Si no lo encuentra, hace un raise de LibroNoDisponibleError con un mensaje claro: "El libro {título} no está disponible o no existe". Consejo: usa la variable del for en minúscula para no confundirla con la clase (L mayúscula).
¿Cómo luce el método buscarolibro?
classBiblioteca:defbuscarolibro(self, titulo):for libro in self.libros:if libro.titulo == titulo and libro.disponible:return libro
raise LibroNoDisponibleError(f"El libro {titulo} no está disponible o no existe")
¿Cómo manejar LibroNoDisponibleError con try y except?
Usa try para lo que puede fallar y captura con except para imprimir el mensaje de la excepción con buena legibilidad.
# Solicitar el título al usuariotitulo =input("Digite el título del libro: ")# Buscar el libro y manejar errorestry: libro = biblioteca.buscarolibro(titulo)print(f"El libro que seleccionaste es {libro.titulo} por {libro.autor}")except LibroNoDisponibleError as e:print(f"Error: {e}")# Nota: dos puntos y espacio tras "Error:".
¿Cómo solicitar y prestar el libro con validaciones?
Con el usuario ya identificado y el libro encontrado, el siguiente paso es Solicitar Libro desde la clase Estudiante (hereda de Usuario). Este método recibe el título y retorna el estado de autorización. Luego, se ejecuta el método prestar del libro: verifica disponibilidad, la marca en falso y aumenta el contador de préstamos. Estas operaciones también deben estar en try/except porque pueden disparar LibroNoDisponibleError.
¿Cómo se autoriza y se presta el libro en main?
# Solicitar el libro por parte del usuarioresultado = usuario.solicitar_libro(titulo)print("\n"+ resultado)# Backslash N para separar visualmente.# Ejecutar el préstamo del librotry: resultado_prestar = libro.prestar()print(resultado_prestar)except LibroNoDisponibleError as e:print(f"Error: {e}")
¿Qué mensajes y resultados verás en la terminal?
“El libro que seleccionaste es … por …”.
“la metamorfosis está autorizado”.
“El libro ha sido prestado exitosamente y el total de préstamos es uno”.
¿Qué buenas prácticas se refuerzan?
Uso de excepciones con mensajes descriptivos: LibroNoDisponibleError.
Validación de disponibilidad antes de prestar: prestar cambia disponible y cuenta usos.
Estructuras try y except solo para lo que puede fallar.
Formatos de salida claros: “Error: mensaje”.
Pruebas con datos erróneos para detectar faltantes de manejo de errores.
¿Con qué datos erróneos probarías y qué validaciones agregarías tú? Comparte tus ideas y resultados en los comentarios.
🌟Sistema de Búsqueda y Préstamo de Libros en Python
🔵 1. Propósito del sistema
📚 Buscar libros por título
🔐 Validar disponibilidad antes del préstamo
⚠️ Gestionar errores con excepciones
🗂️ Utilizar datos externos desde el módulo Data
🧑🏫 Interactuar con el usuario desde consola
🗂️ 2. Componentes del Proyecto
🧱 Módulo Data
⭐ 10 libros
👩🎓 10 estudiantes
🏛️ Clases involucradas
Biblioteca
Usuario
Estudiante → hereda de Usuario
🖥️ main.py
Importa datos de Data
Limpia listas locales antiguas
Conserva el profesor
Ejecuta el flujo completo
🔌 3. Integrando Data en main.py
Pasos esenciales
🔹 Importar listas desde Data
🔹 Borrar listas de libros/estudiantes previas en
🔹 Asignar las importadas a las variables centrales
🔹 Ejecutar:
python main.py
🧑💻 4. Entradas que pide el programa
🔸 Cédula del usuario → identifica al estudiante
🔸 Título del libro → mediante:
input("Digite el título del libro: ")
🔍 5. Búsqueda del Libro en Biblioteca
🎯 Objetivo del método buscarolibro
Recorrer libros
Comparar títulos
Verificar si está disponible
Retornar libro si coincide
Lanzar LibroNoDisponibleError si no existe o está prestado
🧩 Implementación (visual)
class Biblioteca:
def buscarolibro(self, titulo):
for libro in self.libros:
if libro.titulo == titulo and libro.disponible:
return libro
raise LibroNoDisponibleError(
f"El libro {titulo} no está disponible o no existe"
)
🛡️ 6. Manejo de Errores (try/except)
🎯 Uso recomendado:
try → lo que puede fallar
except → manejar error con claridad
titulo = input("Digite el título del libro: ")
try:
libro = biblioteca.buscarolibro(titulo)
print(f"El libro que seleccionaste es {libro.titulo} por {libro.autor}")
except LibroNoDisponibleError as e:
print(f"Error: {e}")
⭐ Formato claro de error:
Error: mensaje
📚 7. Flujo completo de Solicitud + Préstamo
1️⃣ Autorización del estudiante
usuario.solicitar_libro(titulo)
Retorna mensaje (autorizado o no)
2️⃣ Préstamo ejecutado desde Libro
El método prestar():
Verifica disponibilidad
Cambia disponible a False
Aumenta contador de préstamos
Puede lanzar LibroNoDisponibleError
🔧 Ejemplo visual
resultado = usuario.solicitar_libro(titulo)
print("\n" + resultado)
try:
resultado_prestar = libro.prestar()
print(resultado_prestar)
except LibroNoDisponibleError as e:
print(f"Error: {e}")
¿Cómo puedo acceder al código de este curso?
El enlace que aparece no funciona, Lleva a una página 404.
Este es el enlace:
Riesgos y errores potenciales (por archivo)
Uso de usuario o libro después de que su obtención falló: puede producir UnboundLocalError/NameError si buscar_usuario o buscar_libro lanzan y el flujo continúa.
input() puede lanzar EOFError o KeyboardInterrupt en entornos no interactivos.
Búsqueda de libro es sensible a mayúsculas/minúsculas (UX inesperado -> error lógico).
Si no es lista o contiene objetos sin atributos esperados: TypeError / AttributeError.
buscar_usuario y buscar_libro lanzan UsuarioNoEncontradoError / LibroNoDisponibleError (correcto), pero llamantes deben manejar estos errores antes de usar las variables retornadas.
prestar() lanza LibroNoDisponibleError; siempre capturarlo en el código que intenta prestar.
lanza TituloInvalidoError si titulo es vacío.
Import/Module issues si archivos son renombrados o faltan (ModuleNotFoundError, ImportError).
Errores generales a considerar
ModuleNotFoundError / ImportError al cambiar nombres de archivos (asegúrate de sincronizar imports).
AttributeError por objetos mal formados.
TypeError si se recibe None donde se espera lista/iterable.
Errores de E/S interactiva: EOFError, KeyboardInterrupt.
Excepciones personalizadas de (cubrir con BibliotecaError o específicas).
Recomendaciones prácticas (qué capturar y dónde)
Al inicio del flujo interactivo: capturar EOFError y KeyboardInterrupt para salir limpiamente.
Al obtener usuario y libro: usar try/except y terminar o pedir reintento si la búsqueda falla (no seguir usando variables indefinidas).
En llamadas a y : capturar LibroNoDisponibleError, TituloInvalidoError y, si quieres, BibliotecaError general.
Validar inputs: usar s = input(...).strip() y comprobar if not s: ....
Validar estructura de datos antes de iterar: if not isinstance(biblioteca.libros, list): ...
Añadir logs (o prints) con contexto en cada excepción para diagnóstico.
Snippet corto seguro para (ejemplo)
import sys
from exceptions import UsuarioNoEncontradoError, LibroNoDisponibleError, TituloInvalidoError, BibliotecaError
try: cedula =input("Digite el numero cedula: ").strip()except(EOFError, KeyboardInterrupt):print("Entrada interrumpida. Saliendo.") sys.exit(1)try: usuario = biblioteca.buscar_usuario(cedula)except UsuarioNoEncontradoError as e:print(e) sys.exit(1)titulo =input("Digite el titulo del libro: ").strip()ifnot titulo:print("Título vacío. Abortando.") sys.exit(1)try: libro = biblioteca.buscar_libro(titulo)except LibroNoDisponibleError as e:print(e) sys.exit(1)try: resultado = usuario.solicitar_libro(libro.titulo)print(resultado)print(libro.prestar())except(TituloInvalidoError, LibroNoDisponibleError, BibliotecaError)as e:print("Error al procesar préstamo:", e)
Sugerencias adicionales
Considera usar y almacenar títulos normalizados para búsquedas insensibles a mayúsculas.
Centraliza manejo de errores de dominio capturando BibliotecaError en el punto de entrada del programa (main) para evitar duplicación.
Añade tests mínimos que simulen usuarios inexistentes, libros no disponibles y entradas vacías.
from books import Book, PhysicalBook, EBook
from library import Library, UserNotFoundError
from users import Student, Teacher, UserProtocol
from exceptions import LibraryError, BookNotAvailableError