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
Empty file added lib/__init__.py
Empty file.
17 changes: 17 additions & 0 deletions lib/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import logging


def book_added_log(func):
def wrapper(library, book):
res = func(library, book)
logging.info(f"The book has added: {book.get_ribbon()}")
return res
return wrapper


def book_exists(func):
def wrapper(library, book):
if book not in library.books:
raise ValueError("Book not exists")
return func(library, book)
return wrapper
28 changes: 28 additions & 0 deletions lib/library.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from typing import List, Generator
from .models import Book
from .decorators import book_added_log, book_exists


class Library:
def __init__(self, books: List[Book]):
self._books = books

@property
def books(self) -> List[Book]:
return self._books

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.author == author)

@book_added_log
def add(self, book: Book):
self._books.append(book)

@book_exists
def remove(self, book: Book):
self._books.remove(book)


38 changes: 38 additions & 0 deletions lib/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from pydantic import BaseModel


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


class Book:
def __init__(self, model: BookModel):
self._model = model

@property
def title(self) -> str:
return self._model.title

@property
def author(self) -> str:
return self._model.author

@property
def year(self) -> int:
return self._model.year

def get_ribbon(self) -> str:
return f"{self.title} by {self.author}, published in {self.year}"

def __str__(self):
return f"Book(title={self.title}, author={self.author}, year={self.year})"


class Magazine(Book):
def __init__(self, model: BookModel):
super().__init__(model)

def get_ribbon(self) -> str:
return f"The {self.title} magazine by {self.author}, published in {self.year}"
27 changes: 27 additions & 0 deletions lib/storage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import json
from contextlib import contextmanager
from .library import Library
from .models import Book, BookModel


@contextmanager
def file_manager(file_name: str, mode: str):
file = open(file_name, mode)
try:
yield file
finally:
file.close()


def save(library: Library, file_name: str):
with file_manager(file_name, 'w') as file:
books_data = [book._model.dict() for book in library]
json.dump(books_data, file)


def load(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_model))
51 changes: 42 additions & 9 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,49 @@
# This is a sample Python script.
from lib.models import Book, BookModel, Magazine
from lib.library import Library
from lib import storage

# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.
FILE_NAME = "test.json"


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.
def print_books(library: Library):
print("===============")
for book in library:
print(f"Book: {book}")


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
print_hi('PyCharm')
library = Library([])

# See PyCharm help at https://www.jetbrains.com/help/pycharm/
book1 = Book(BookModel(title="To Kill a Mockingbird", author="Harper Lee",
year=1960))
book2 = Book(BookModel(title="1984", author="George Orwell",
year=1949))
book3 = Book(
BookModel(title="The Great Gatsby", author="F. Scott Fitzgerald",
year=1925))

magazine1 = Magazine(
BookModel(title="National Geographic", author="Multiple Authors",
year=2020))
magazine2 = Magazine(BookModel(title="Time", author="Multiple Authors",
year=2021))

library.add(book1)
library.add(book2)
library.add(book3)
library.add(magazine1)
library.add(magazine2)

print_books(library)

print("=========")
for book in library.books_by_author("Multiple Authors"):
print(f"Multiple Authors: {book}")

storage.save(library, FILE_NAME)

library.remove(magazine2)
print_books(library)

storage.load(library, FILE_NAME)
print_books(library)