Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions library_management/book.py
Original file line number Diff line number Diff line change
@@ -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}"
7 changes: 7 additions & 0 deletions library_management/book_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from pydantic import BaseModel

class BookModel(BaseModel):
title: str
author: str
year_of_publication: int

11 changes: 11 additions & 0 deletions library_management/comics.py
Original file line number Diff line number Diff line change
@@ -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})"

25 changes: 25 additions & 0 deletions library_management/context_manager.py
Original file line number Diff line number Diff line change
@@ -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))
10 changes: 10 additions & 0 deletions library_management/journal.py
Original file line number Diff line number Diff line change
@@ -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}"
47 changes: 47 additions & 0 deletions library_management/library.py
Original file line number Diff line number Diff line change
@@ -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)
40 changes: 30 additions & 10 deletions main.py
Original file line number Diff line number Diff line change
@@ -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())