Interfaz de administrador
Parte de la sección Object Oriented Programming del Journey de Python de Coddy — lección 59 de 64.
Desafío
IntermedioEn este desafío, implementarás funciones administrativas para un sistema de gestión de bibliotecas.
Deberás modificar el archivo library.py para agregar un método get_statistics a la clase Library que devuelva un diccionario con estadísticas clave sobre el estado de la biblioteca. Los detalles de la implementación se proporcionan en los comentarios TODO dentro del archivo.
Las estadísticas deben incluir:
- Número total de libros
- Conteo de libros disponibles
- Conteo de libros prestados
- Número total de usuarios
- Número de usuarios con libros prestados
Los archivos book.py y user.py contienen clases pre-implementadas con las que interactuará tu solución. Si bien puedes revisar estos archivos para comprender la estructura del sistema, tu implementación debe centrarse en el archivo library.py.
Hoja de referencia
Este desafío se centra en implementar estadísticas de un sistema de gestión de bibliotecas sin proporcionar contenido de lección específico. La tarea consiste en crear un método get_statistics que devuelva un diccionario con métricas de la biblioteca, como el total de libros, libros disponibles, libros prestados, total de usuarios y usuarios con libros prestados.
Pruébalo tú mismo
from book import Book
from user import User
from library import Library
# Manejador de casos de prueba
test_case = input()
if test_case == "empty_library":
library = Library("Empty Library")
stats = library.get_statistics()
print(f"Total Books: {stats['total_books']}")
print(f"Available Books: {stats['available_books']}")
print(f"Borrowed Books: {stats['borrowed_books']}")
print(f"Total Users: {stats['total_users']}")
print(f"Users with Books: {stats['users_with_books']}")
elif test_case == "with_borrowed_books":
library = Library("Community Library")
# Agregar libros y usuarios
library.add_book(Book("The Great Gatsby", "F. Scott Fitzgerald", "123456"))
library.add_book(Book("To Kill a Mockingbird", "Harper Lee", "789012"))
library.add_book(Book("1984", "George Orwell", "345678"))
library.add_user(User("U001", "Alice"))
library.add_user(User("U002", "Bob"))
library.add_user(User("U003", "Charlie"))
# Prestar algunos libros
library.borrow_book("123456", "U001")
library.borrow_book("789012", "U001") # Alice presta 2 libros
library.borrow_book("345678", "U002") # Bob presta 1 libro
stats = library.get_statistics()
print(f"Total Books: {stats['total_books']}")
print(f"Available Books: {stats['available_books']}")
print(f"Borrowed Books: {stats['borrowed_books']}")
print(f"Total Users: {stats['total_users']}")
print(f"Users with Books: {stats['users_with_books']}")
elif test_case == "return_books":
library = Library("Return Test Library")
# Agregar libros y usuarios
library.add_book(Book("Python Programming", "John Smith", "111222"))
library.add_book(Book("Data Structures", "Jane Doe", "333444"))
library.add_user(User("U101", "David"))
library.add_user(User("U102", "Emma"))
# Prestar un libro
library.borrow_book("111222", "U101")
# Obtener estadísticas antes de devolver
stats_before = library.get_statistics()
print("Before returning:")
print(f"Total Books: {stats_before['total_books']}")
print(f"Available Books: {stats_before['available_books']}")
print(f"Borrowed Books: {stats_before['borrowed_books']}")
print(f"Users with Books: {stats_before['users_with_books']}")
# Implementación de devolución de libro (estaría en la clase Library)
book = next((book for book in library.books if book.isbn == "111222"), None)
user = next((user for user in library.users if user.user_id == "U101"), None)
if book and user:
book.available = True
book.borrower = None
user.books_borrowed.remove(book)
print("Book returned successfully")
# Obtener estadísticas después de devolver
stats_after = library.get_statistics()
print("\
After returning:")
print(f"Total Books: {stats_after['total_books']}")
print(f"Available Books: {stats_after['available_books']}")
print(f"Borrowed Books: {stats_after['borrowed_books']}")
print(f"Users with Books: {stats_after['users_with_books']}")
elif test_case == "edge_cases":
# Biblioteca vacía
empty_library = Library("Empty Library")
empty_stats = empty_library.get_statistics()
print("Empty library statistics:")
print(f"Total Books: {empty_stats['total_books']}")
print(f"Available Books: {empty_stats['available_books']}")
print(f"Borrowed Books: {empty_stats['borrowed_books']}")
print(f"Total Users: {empty_stats['total_users']}")
print(f"Users with Books: {empty_stats['users_with_books']}")
# Libros pero sin usuarios
books_only = Library("Books Only")
books_only.add_book(Book("Book 1", "Author 1", "B001"))
books_only.add_book(Book("Book 2", "Author 2", "B002"))
books_stats = books_only.get_statistics()
print("\
Library with books but no users:")
print(f"Total Books: {books_stats['total_books']}")
print(f"Available Books: {books_stats['available_books']}")
print(f"Total Users: {books_stats['total_users']}")
print(f"Users with Books: {books_stats['users_with_books']}")
# Usuarios pero sin libros
users_only = Library("Users Only")
users_only.add_user(User("U201", "User 1"))
users_only.add_user(User("U202", "User 2"))
users_stats = users_only.get_statistics()
print("\
Library with users but no books:")
print(f"Total Books: {users_stats['total_books']}")
print(f"Available Books: {users_stats['available_books']}")
print(f"Total Users: {users_stats['total_users']}")
print(f"Users with Books: {users_stats['users_with_books']}")
# Casos de error
error_library = Library("Error Test")
error_library.add_book(Book("Error Book", "Error Author", "E001"))
error_library.add_user(User("E101", "Error User"))
print("\
Error cases:")
print(f"Borrow non-existent book: {error_library.borrow_book('NONEXISTENT', 'E101')}")
print(f"Borrow with non-existent user: {error_library.borrow_book('E001', 'NONEXISTENT')}")
elif test_case == "large_library":
large_library = Library("Large Library")
# Agregar 100 libros
for i in range(1, 101):
large_library.add_book(Book(f"Book {i}", f"Author {i}", f"ISBN{i:06d}"))
# Agregar 100 usuarios
for i in range(1, 101):
large_library.add_user(User(f"U{i:03d}", f"User {i}"))
# Hacer que 50 usuarios presten libros
for i in range(1, 51):
large_library.borrow_book(f"ISBN{i:06d}", f"U{i:03d}")
# Hacer que algunos usuarios presten múltiples libros
for i in range(1, 11):
large_library.borrow_book(f"ISBN{i+50:06d}", f"U{i:03d}")
stats = large_library.get_statistics()
print("Large library statistics:")
print(f"Total Books: {stats['total_books']}")
print(f"Available Books: {stats['available_books']}")
print(f"Borrowed Books: {stats['borrowed_books']}")
print(f"Total Users: {stats['total_users']}")
print(f"Users with Books: {stats['users_with_books']}")
# Verificar cálculos
print("\
Verification:")
print(f"Total books should be 100: {stats['total_books'] == 100}")
print(f"Borrowed books should be 60: {stats['borrowed_books'] == 60}")
print(f"Available books should be 40: {stats['available_books'] == 40}")
print(f"Users with books should be 50: {stats['users_with_books'] == 50}")
elif test_case == "statistics_accuracy":
accuracy_library = Library("Accuracy Test")
# Agregar exactamente 10 libros
for i in range(1, 11):
accuracy_library.add_book(Book(f"Book {i}", f"Author {i}", f"A{i:03d}"))
# Agregar exactamente 5 usuarios
for i in range(1, 6):
accuracy_library.add_user(User(f"AU{i}", f"Accuracy User {i}"))
# Ningún libro prestado todavía
stats1 = accuracy_library.get_statistics()
print("Initial state:")
print(f"Total Books: {stats1['total_books']} (Expected: 10)")
print(f"Available Books: {stats1['available_books']} (Expected: 10)")
print(f"Borrowed Books: {stats1['borrowed_books']} (Expected: 0)")
print(f"Total Users: {stats1['total_users']} (Expected: 5)")
print(f"Users with Books: {stats1['users_with_books']} (Expected: 0)")
# Hacer que 3 usuarios presten libros
accuracy_library.borrow_book("A001", "AU1")
accuracy_library.borrow_book("A002", "AU1") # El usuario 1 presta 2 libros
accuracy_library.borrow_book("A003", "AU2") # El usuario 2 presta 1 libro
accuracy_library.borrow_book("A004", "AU3") # El usuario 3 presta 1 libro
stats2 = accuracy_library.get_statistics()
print("\
After borrowing:")
print(f"Total Books: {stats2['total_books']} (Expected: 10)")
print(f"Available Books: {stats2['available_books']} (Expected: 6)")
print(f"Borrowed Books: {stats2['borrowed_books']} (Expected: 4)")
print(f"Total Users: {stats2['total_users']} (Expected: 5)")
print(f"Users with Books: {stats2['users_with_books']} (Expected: 3)")Todas las lecciones de Object Oriented Programming
1Fundamentos de la POO
Archivos externosIntroducción a la POOClases vs ObjetosEl parámetro selfMétodosAtributosMétodo constructor (__init__)Resumen - Calculadora simple4Herencia
Herencia básicaLa función super()Sobrescritura de métodosHerencia múltipleOrden de resolución de métodosResumen - Jerarquía de empleados7Métodos especiales
Introducción a los métodos mágicosSobrecarga de operadoresMétodos mágicos de contenedoresRepaso - Lista personalizada10Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy2Decoradores
Introducción a los decoradoresDecorador propertyDecorador de métodos estáticosDecorador de métodos de clase5Polimorfismo
Sobreescritura de métodos revisitadaDuck TypingClases y métodos abstractosDiseño de interfacesResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaMixinsMétodos estáticos y de claseDecoradores de claseGestores de contexto11Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite3Propiedades de clase
Variables de instancia vs de claseDecoradores de propiedadesAtributos privadosResumen - Gestor de cuentas bancarias6Encapsulamiento
Miembros públicos, protegidos y privadosModificadores de accesoOcultamiento de informaciónDecoradores de propiedades avanzadosResumen - Sistema de registros de estudiantes12Proyecto: Gestión de biblioteca
Descripción general del proyectoClases de Libros y Usuarios