class Book:
def __init__(self, title, last, first):
self._title = title #A
self._last = last #A
self._first = first #A
@property #B
def title(self): return self._title #B
#B
@property #B
def last(self): return self._last #B
#B
@property #B
def first(self): return self._first #B
def __str__(self):
return (f"{{TITLE: '{self._title}', LAST: '{self._last}', " #C
f"FIRST: '{self._first}'}}") #C
26 OOP: Book Catalog
26.1 Iteration 1
26.1.1 Book
Class
26.1.2 Catalogue
Class
class Catalogue:
@staticmethod
def _equal_ignore_case(target_str, other_str):
if len(target_str) == 0:
return True
else:
return target_str.casefold() == other_str.casefold()
def __init__(self):
self._booklist = []
def add(self, title, last, first):
= Book(title, last, first)
book self._booklist.append(book)
def _is_match(self, book, target):
return ( Catalogue._equal_ignore_case(target.title,
book.title)and Catalogue._equal_ignore_case(target.last,
book.last)and Catalogue._equal_ignore_case(target.first,
book.first)
)
def find(self, target):
return [book for book in self._booklist
if self._is_match(book, target)
]
26.1.3 Usage
def fill(catalogue): #A
"Life of Pi", "Martel", "Yann")
catalogue.add("The Call of the Wild", "London", "Jack")
catalogue.add(
"To Kill a Mockingbird", "Lee", "Harper")
catalogue.add("Little Women", "Alcott", "Louisa")
catalogue.add(
"The Adventures of Sherlock Holmes", "Doyle", "Conan")
catalogue.add("And Then There Were None", "Christie", "Agatha")
catalogue.add(
"Carrie", "King", "Stephen")
catalogue.add("It: A Novel", "King", "Stephen")
catalogue.add("Frankenstein", "Shelley", "Mary")
catalogue.add(
"2001: A Space Odyssey", "Clarke", "Arthur")
catalogue.add("Ender's Game", "Card", "Orson")
catalogue.add(
def search(catalogue, target): #B
print()
print("Find ", end="")
print(target)
= catalogue.find(target)
matches
if len(matches) == 0:
print("No matches.")
else:
print("Matches:")
for book in matches:
print(" ", end="")
print(book)
def test(catalogue): #C
= Book("Life of Pi", "Martel", "Yann")
target
search(catalogue, target)
= Book("", "King", "")
target
search(catalogue, target)
= Book("1984", "Orwell", "George")
target
search(catalogue, target)
= Book("", "", "") #D
target
search(catalogue, target)
= Catalogue()
catalogue
fill(catalogue) test(catalogue)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[23], line 49 45 search(catalogue, target) 48 catalogue = Catalogue() ---> 49 fill(catalogue) 50 test(catalogue) Cell In[23], line 2, in fill(catalogue) 1 def fill(catalogue): #A ----> 2 catalogue.add("Life of Pi", "Martel", "Yann") 3 catalogue.add("The Call of the Wild", "London", "Jack") 5 catalogue.add("To Kill a Mockingbird", "Lee", "Harper") TypeError: Catalogue.add() takes 2 positional arguments but 4 were given
26.2 Iteration 2
26.2.1 Genre(Enum)
from enum import Enum
class Genre(Enum): #A
= 0
UNSPECIFIED = 1
ADVENTURE = 2
CLASSICS = 3
DETECTIVE = 4
FANTASY = 5
HISTORIC = 6
HORROR = 7
ROMANCE = 8
SCIFI
def __str__(self): return self.name.lower()
Genre.ADVENTURE
<Genre.ADVENTURE: 1>
print(Genre.ADVENTURE)
print(Genre(1))
adventure
adventure
# Iterate through all defined genres
for genre in Genre:
print(genre)
unspecified
adventure
classics
detective
fantasy
historic
horror
romance
scifi
26.2.2 Attributes
class Attributes:
@staticmethod
def _equal_ignore_case(target_str, other_str): #D
if len(target_str) == 0:
return True
else:
return target_str.casefold() == other_str.casefold()
def __init__(self, title, last, first, year, genre):
self._title = title
self._last = last
self._first = first
self._year = year #C
self._genre = genre #C
@property
def title(self): return self._title
@property
def last(self): return self._last
@property
def first(self): return self._first
@property
def year(self): return self._year
@property
def genre(self): return self._genre
def is_match(self, target_attrs): #B
return (
Attributes._equal_ignore_case(target_attrs.title, self._title)
and Attributes._equal_ignore_case(target_attrs.last,
self._last)
and Attributes._equal_ignore_case(target_attrs.first,
self._first)
and ( (target_attrs.year == 0)
or (target_attrs.year == self._year))
and ( (target_attrs.genre == Genre.UNSPECIFIED)
or (target_attrs.genre == self._genre))
)def __str__(self):
return (f"{{TITLE: '{self._title}', LAST: '{self._last}', "
f"FIRST: '{self._first}', YEAR: {self._year}, " #E
f"GENRE: {self._genre}}}") #E
26.2.3 Book
& Catalogue
class Book:
def __init__(self, attributes):
self._attributes = attributes
@property
def attributes(self): return self._attributes
class Catalogue:
def __init__(self):
self._booklist = []
def add(self, attrs):
self._booklist.append(Book(attrs)) #A
def find(self, target_attrs):
return [book for book in self._booklist
if book.attributes.is_match(target_attrs) #B
]
26.2.4 Usage
= Catalogue()
catalogue
"The Call of the Wild",
catalogue.add(Attributes("London", "Jack",
1903, Genre.ADVENTURE))
"To Kill a Mockingbird",
catalogue.add(Attributes("Lee", "Harper",
1960, Genre.CLASSICS))
= Attributes("Life of Pi", "Martel", "Yann",
target_attrs 2003, Genre.ADVENTURE)
search(catalogue, target_attrs)
Find {TITLE: 'Life of Pi', LAST: 'Martel', FIRST: 'Yann', YEAR: 2003, GENRE: adventure}
No matches.