diff --git a/library_management/book.py b/library_management/book.py new file mode 100644 index 0000000..c887922 --- /dev/null +++ b/library_management/book.py @@ -0,0 +1,8 @@ +from .book_model import BookModel + +class Book: + def __init__(self, book_model: BookModel): + self._book_model = book_model + + def get_ribbon(self) -> str: + return f"{self._book_model.title} by {self._book_model.author}, published in {self._book_model.year_of_publication}" diff --git a/library_management/book_model.py b/library_management/book_model.py new file mode 100644 index 0000000..23052e3 --- /dev/null +++ b/library_management/book_model.py @@ -0,0 +1,7 @@ +from pydantic import BaseModel + +class BookModel(BaseModel): + title: str + author: str + year_of_publication: int + \ No newline at end of file diff --git a/library_management/comics.py b/library_management/comics.py new file mode 100644 index 0000000..66f79fe --- /dev/null +++ b/library_management/comics.py @@ -0,0 +1,11 @@ +from book import Book + +class Comics(Book): + def __init__(self, title, author, illustrator, series, *args, **kwargs): + super().__init__(title, author, *args, **kwargs) + self.illustrator = illustrator + self.series = series + + def __str__(self): + return f"{self.title} by {self.author}, illustrated by {self.illustrator} (Series: {self.series})" + \ No newline at end of file diff --git a/library_management/context_manager.py b/library_management/context_manager.py new file mode 100644 index 0000000..7c321f1 --- /dev/null +++ b/library_management/context_manager.py @@ -0,0 +1,25 @@ +import json +from contextlib import contextmanager +from .library import Library +from .book_model import BookModel +from .book import Book + +@contextmanager +def file_manager(file_name: str, mode: str): + file = open(file_name, mode) + try: + yield file + finally: + file.close() + +def save_books_to_file(library: Library, file_name: str): + with file_manager(file_name, 'w') as file: + books_data = [book._book_model.dict() for book in library._books] + json.dump(books_data, file) + +def load_books_from_file(library: Library, file_name: str): + with file_manager(file_name, 'r') as file: + books_data = json.load(file) + for book_data in books_data: + book_model = BookModel(**book_data) + library.add_book(Book(book_model)) diff --git a/library_management/journal.py b/library_management/journal.py new file mode 100644 index 0000000..d75e976 --- /dev/null +++ b/library_management/journal.py @@ -0,0 +1,10 @@ +from .book import Book +from .book_model import BookModel + +class Journal(Book): + def __init__(self, book_model: BookModel, issue_number: int): + super().__init__(book_model) + self._issue_number = issue_number + + def get_ribbon(self) -> str: + return f"{self._book_model.title} by {self._book_model.author}, published in {self._book_model.year_of_publication}, Issue: {self._issue_number}" diff --git a/library_management/library.py b/library_management/library.py new file mode 100644 index 0000000..2aabb76 --- /dev/null +++ b/library_management/library.py @@ -0,0 +1,47 @@ +from typing import List, Generator +import logging +from .book import Book +from .comics import Comics + +logging.basicConfig(level=logging.INFO) + +def log_addition(func): + def wrapper(library, book): + logging.info(f"Adding book: {book.get_ribbon()}") + return func(library, book) + return wrapper + +def check_book_exists(func): + def wrapper(library, book): + if book not in library._books: + raise ValueError("Book not found in the library") + return func(library, book) + return wrapper + +class Library: + def __init__(self): + self._books: List[Book] = [] + self.initialize_starter_books() + + def initialize_starter_books(self): + starter_books = [ + Book(title="Кайдашева сім'я", author="Іван Семенович Нечуй-Левицький"), + Book(title="Лісова пісня", author="Леся Українка"), + Comics(title="Star Wars Knights of the Old Republic 43: The Reaping, Part 1", author="John Jackson Miller", illustrator="Dustin Weaver", series="Star Wars: Knights of the Old Republic"), + Comics(title="Unseen, Unheard", author="Chris Avellone", illustrator="Dustin Weaver", series="Star Wars Tales") + ] + self._books.extend(starter_books) + + @log_addition + def add_book(self, book: Book): + self._books.append(book) + + @check_book_exists + def remove_book(self, book: Book): + self._books.remove(book) + + def __iter__(self): + return iter(self._books) + + def books_by_author(self, author: str) -> Generator[Book, None, None]: + return (book for book in self._books if book._book_model.author == author) diff --git a/main.py b/main.py index 94e3a87..5602d85 100644 --- a/main.py +++ b/main.py @@ -1,16 +1,36 @@ -# This is a sample Python script. +from library_management.book_model import BookModel +from library_management.book import Book +from library_management.library import Library +from library_management.context_manager import save_books_to_file, load_books_from_file +from library_management.journal import Journal -# Press ⌃R to execute it or replace it with your code. -# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings. +if __name__ == "__main__": + library = Library() + book1 = Book(BookModel(title="Book One", author="Author A", year_of_publication=2001)) + book2 = Journal(BookModel(title="Journal One", author="Author B", year_of_publication=2005), issue_number=1) -def print_hi(name): - # Use a breakpoint in the code line below to debug your script. - print(f'Hi, {name}') # Press ⌘F8 to toggle the breakpoint. + library.add_book(book1) + library.add_book(book2) + print("List of books in the library:") + for book in library: + print(book.get_ribbon()) -# Press the green button in the gutter to run the script. -if __name__ == '__main__': - print_hi('PyCharm') + print("\nBooks by Author A:") + for book in library.books_by_author("Author A"): + print(book.get_ribbon()) -# See PyCharm help at https://www.jetbrains.com/help/pycharm/ + save_books_to_file(library, "library_books.json") + + library.remove_book(book1) + + print("\nList of books after deletion:") + for book in library: + print(book.get_ribbon()) + + load_books_from_file(library, "library_books.json") + + print("\nList of books after loading from file:") + for book in library: + print(book.get_ribbon())