|
| 1 | +#26 { Retos para Programadores } Principio SOLID de Responsabilidad Única (Single Responsibility Principle, SRP) |
| 2 | + |
| 3 | +# Bibliography reference |
| 4 | +# I use GPT as a reference and sometimes to correct or generate proper comments. |
| 5 | + |
| 6 | +""" |
| 7 | + * EJERCICIO: |
| 8 | + * Explora el "Principio SOLID de Responsabilidad Única (Single Responsibility |
| 9 | + * Principle, SRP)" y crea un ejemplo simple donde se muestre su funcionamiento |
| 10 | + * de forma correcta e incorrecta. |
| 11 | + * |
| 12 | + * DIFICULTAD EXTRA (opcional): |
| 13 | + * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita |
| 14 | + * manejar diferentes aspectos como el registro de libros, la gestión de usuarios |
| 15 | + * y el procesamiento de préstamos de libros. |
| 16 | + * Requisitos: |
| 17 | + * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con |
| 18 | + * información básica como título, autor y número de copias disponibles. |
| 19 | + * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con |
| 20 | + * información básica como nombre, número de identificación y correo electrónico. |
| 21 | + * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios |
| 22 | + * tomar prestados y devolver libros. |
| 23 | + * Instrucciones: |
| 24 | + * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje |
| 25 | + * los tres aspectos mencionados anteriormente (registro de libros, registro de |
| 26 | + * usuarios y procesamiento de préstamos). |
| 27 | + * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases |
| 28 | + * siguiendo el Principio de Responsabilidad Única. |
| 29 | + |
| 30 | + """ |
| 31 | + |
| 32 | +""" Single Responsibility Principle |
| 33 | +A computer programming principle that states that every module, class, or |
| 34 | +function should have responsibility over a single part of the functionality |
| 35 | +provided by the software, and that responsibility should be entirely |
| 36 | +encapsulated by the module, class, or function. All its services should be |
| 37 | +narrowly aligned with that responsibility. """ |
| 38 | + |
| 39 | +log = print |
| 40 | +log('Retos para Programadores #26') |
| 41 | + |
| 42 | +# Not Following the Single Responsibility Principle (SRP) |
| 43 | + |
| 44 | +class Library: |
| 45 | + def __init__(self): |
| 46 | + self.books = [] |
| 47 | + self.users = [] |
| 48 | + self.loans = [] |
| 49 | + |
| 50 | + def add_book(self, title, author, copies): |
| 51 | + self.books.append({'title': title, 'author': author, 'copies': copies}) |
| 52 | + |
| 53 | + def register_user(self, name, user_id, email): |
| 54 | + self.users.append({'name': name, 'id': user_id, 'email': email}) |
| 55 | + |
| 56 | + def loan_book(self, user_id, book_title): |
| 57 | + user = next((u for u in self.users if u['id'] == user_id), None) |
| 58 | + book = next((b for b in self.books if b['title'] == book_title), None) |
| 59 | + |
| 60 | + if user and book and book['copies'] > 0: |
| 61 | + self.loans.append({'userId': user_id, 'bookTitle': book_title}) |
| 62 | + book['copies'] -= 1 |
| 63 | + log(f'Book "{book_title}" loaned to {user["name"]}') |
| 64 | + else: |
| 65 | + log("Loan failed: User or book not found, or no copies available.") |
| 66 | + |
| 67 | +# Example usage |
| 68 | +library = Library() |
| 69 | +library.add_book("Learn Bash the Hard Way", "Ian Miell", 2) |
| 70 | +library.add_book("MATLAB Notes for Professionals", "GoalKicker.com", 4) |
| 71 | +library. register_user( "Royer Rabit", "006", "[email protected]") |
| 72 | +library.loan_book("006", "MATLAB Notes for Professionals") # Book "MATLAB Notes for Professionals" loaned to Royer Rabit |
| 73 | + |
| 74 | + |
| 75 | +import logging |
| 76 | + |
| 77 | +# Set up logging configuration |
| 78 | +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') |
| 79 | + |
| 80 | +# Define logging functions |
| 81 | +def log_info(message): |
| 82 | + logging.info(message) |
| 83 | + |
| 84 | +def log_warning(message): |
| 85 | + logging.warning(message) |
| 86 | + |
| 87 | +def log_error(message): |
| 88 | + logging.error(message) |
| 89 | + |
| 90 | +# Book class |
| 91 | +class Book: |
| 92 | + def __init__(self, title, author, copies): |
| 93 | + self.title = title |
| 94 | + self.author = author |
| 95 | + self.copies = copies |
| 96 | + |
| 97 | +# User class |
| 98 | +class User: |
| 99 | + def __init__(self, name, user_id, email): |
| 100 | + self.name = name |
| 101 | + self.id = user_id |
| 102 | + self.email = email |
| 103 | + |
| 104 | +# BookManager class |
| 105 | +class BookManager: |
| 106 | + def __init__(self): |
| 107 | + self.books = [] |
| 108 | + |
| 109 | + def add_book(self, title, author, copies): |
| 110 | + self.books.append(Book(title, author, copies)) |
| 111 | + log_info(f"Book added: {title} by {author} with {copies} copies.") |
| 112 | + |
| 113 | + def get_books(self): |
| 114 | + return self.books |
| 115 | + |
| 116 | + def find_book(self, title): |
| 117 | + return next((book for book in self.books if book.title == title), None) |
| 118 | + |
| 119 | + def increase_copies(self, book_title): |
| 120 | + book = self.find_book(book_title) |
| 121 | + if book: |
| 122 | + book.copies += 1 |
| 123 | + log_info(f"Increased copies for book: {book_title}") |
| 124 | + |
| 125 | +# Function to search books by partial title |
| 126 | +def search_books_by_partial_title(books, search_term): |
| 127 | + return [book for book in books if search_term.lower() in book.title.lower()] |
| 128 | + |
| 129 | +# UserManager class |
| 130 | +class UserManager: |
| 131 | + def __init__(self): |
| 132 | + self.users = [] |
| 133 | + |
| 134 | + def register_user(self, name, user_id, email): |
| 135 | + self.users.append(User(name, user_id, email)) |
| 136 | + log_info(f"User registered: {name} with ID: {user_id}") |
| 137 | + |
| 138 | + def find_user(self, user_id): |
| 139 | + return next((user for user in self.users if user.id == user_id), None) |
| 140 | + |
| 141 | +# LoanManager class |
| 142 | +class LoanManager: |
| 143 | + def __init__(self): |
| 144 | + self.loans = [] |
| 145 | + self.next_loan_id = 1 |
| 146 | + |
| 147 | + def loan_book(self, user, book): |
| 148 | + if book.copies > 0: |
| 149 | + loan_id = self.next_loan_id |
| 150 | + self.loans.append({'loan_id': loan_id, 'user_id': user.id, 'book_title': book.title}) |
| 151 | + book.copies -= 1 |
| 152 | + log_info(f"Book \"{book.title}\" loaned to {user.name} with Loan ID: {loan_id}") |
| 153 | + self.next_loan_id += 1 |
| 154 | + else: |
| 155 | + log_warning("Loan failed: No copies available.") |
| 156 | + |
| 157 | + def return_book(self, loan_id, book_manager): |
| 158 | + loan_index = next((index for index, loan in enumerate(self.loans) if loan['loan_id'] == loan_id), None) |
| 159 | + |
| 160 | + if loan_index is not None: |
| 161 | + loan = self.loans[loan_index] |
| 162 | + book = book_manager.find_book(loan['book_title']) |
| 163 | + if book: |
| 164 | + book.copies += 1 |
| 165 | + log_info(f"Book \"{loan['book_title']}\" returned with Loan ID: {loan_id}") |
| 166 | + del self.loans[loan_index] |
| 167 | + else: |
| 168 | + log_error("Return failed: No loan record found for this Loan ID.") |
| 169 | + |
| 170 | + def get_loans_by_partial_book_title(self, search_term, user_id): |
| 171 | + return [loan for loan in self.loans if search_term.lower() in loan['book_title'].lower() and loan['user_id'] == user_id] |
| 172 | + |
| 173 | +# Example usage of the library system |
| 174 | +book_manager = BookManager() |
| 175 | +user_manager = UserManager() |
| 176 | +loan_manager = LoanManager() |
| 177 | + |
| 178 | +book_manager.add_book("300 JavaScript Interview Mastery Questions Dive Deep into JavaScript Theory, Syntax, and APIs, and Interview with Confidence", "Middaugh, Jonathan", 3) |
| 179 | +book_manager.add_book("Javascript Interview Questions and Answers", "Bandal, Pratik", 7) |
| 180 | +book_manager.add_book("100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...", "Aimee Mills", 2) |
| 181 | +user_manager. register_user( "Niko Zen", "008", "[email protected]") |
| 182 | + |
| 183 | +search_term1 = "JavaScript" |
| 184 | +search_term2 = "Interview Questions" |
| 185 | + |
| 186 | +search_results1 = search_books_by_partial_title(book_manager.get_books(), search_term1) |
| 187 | +search_results2 = search_books_by_partial_title(book_manager.get_books(), search_term2) |
| 188 | + |
| 189 | +log_info(f"Search results for '{search_term1}': {[book.title for book in search_results1]}") |
| 190 | +log_info(f"Search results for '{search_term2}': {[book.title for book in search_results2]}") |
| 191 | + |
| 192 | +user = user_manager.find_user("008") |
| 193 | +book_title = search_results1[2].title if len(search_results1) > 2 else None |
| 194 | +book = book_manager.find_book(book_title) |
| 195 | + |
| 196 | +if book: |
| 197 | + loan_manager.loan_book(user, book) # Loan the book to the user |
| 198 | + loans = loan_manager.get_loans_by_partial_book_title(book.title, user.id) |
| 199 | + if loans: |
| 200 | + loan_manager.return_book(loans[0]['loan_id'], book_manager) # Return the book |
| 201 | +else: |
| 202 | + log_warning("Book not found for loan.") |
| 203 | + |
| 204 | +# Output: |
| 205 | + """ |
| 206 | +2024-12-25 12:09:59,513 - INFO - Book added: 300 JavaScript Interview Mastery Questions Dive Deep into JavaScript Theory, Syntax, and APIs, and Interview with Confidence by Middaugh, Jonathan with 3 copies. |
| 207 | +2024-12-25 12:09:59,513 - INFO - Book added: Javascript Interview Questions and Answers by Bandal, Pratik with 7 copies. |
| 208 | +2024-12-25 12:09:59,513 - INFO - Book added: 100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT... by Aimee Mills with 2 copies. |
| 209 | +2024-12-25 12:09:59,513 - INFO - User registered: Niko Zen with ID: 008 |
| 210 | +2024-12-25 12:09:59,514 - INFO - Search results for 'JavaScript': ['300 JavaScript Interview Mastery Questions Dive Deep into JavaScript Theory, Syntax, and APIs, and Interview with Confidence', 'Javascript Interview Questions and Answers', '100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT...'] |
| 211 | +2024-12-25 12:09:59,514 - INFO - Search results for 'Interview Questions': ['Javascript Interview Questions and Answers'] |
| 212 | +2024-12-25 12:09:59,515 - INFO - Book "100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT..." loaned to Niko Zen with Loan ID: 1 |
| 213 | +2024-12-25 12:09:59,515 - INFO - Book "100 MOST ASKED JOB READY QUESTIONS ANSWERS IN THE TECH SPACE Here are the most asked questions in PYTHON, SQL, JAVASCRIPT..." returned with Loan ID: 1 |
| 214 | + |
| 215 | + """ |
0 commit comments