파이썬 클래스 연습문제 3 - 도서관 관리 시스템 만들기
문제: 도서관 관리 시스템을 만들어보자.
도서관에 책을 추가하고, 도서관 회원들이 책을 대출하고 반납하는 프로그램을 작성해보세요.
책 클래스를 생성한다. 이 클래스는 제목, 저자, isbn를 속성으로 가진다.도서관 클래스를 생성한다. 도서관은 책을 추가하거나 제거할 수 있고, 책을 찾아볼 수도 있다. 모든 책을 확인하고, 대출 중인 책은 리스트를 만들어서 관리한다. 회원 클래스를 생성한다. 회원은 이름 정보를 받는다. 회원이 책을 빌리고, 다시 되돌려주는 메서드를 만든다.
1. Book 클래스
먼저 Book이라는 클래스를 만든다. Book 클래스로 책을 찍어낼 거고(=객체를 만든다), 찍어낸 책(객체)에는 제목, 저자, isbn, 그리고 대출여부를 판단할 수 있는 값(속성들)을 가지고 있게 만든다.
class Book:
def __init__(self, title, author, isbn):
self.title = title
self.author = author
self.isbn = isbn
self.available = True
#들여쓰기 잘 확인하자!! 꼭 들여쓰기 빼먹어서 에러남!!
def __str__(self):
return f"'{self.title}' by {self.author} (ISBN: {self.isbn})"
book1 = Book("pythonstudybook", "킹왕짱교수", 12345678
__init__ 메서드
Book 객체를 초기화한다. 처음 Book 객체를 만들 때 초기값으로 받을 정보들(제목, 저자, ISBN)을 설정하고, 책의 가용성(availability)을 True로 설정한다. 여기서 self는 생성되는 객체 자신을 가리킨다.
book1 이라는 객체를 Book 클래스로 만들 때, book1.title은 Book(title)에서 받은 pythonstudybook이 된다. 다른 것도 마찬가지.
self.속성(book1.속성) = __init__으로 받았던 속성값
__str__ 메서드
Book 객체를 문자열로 표현한다. 이 메서드는 객체를 출력하거나 문자열로 변환할 때 자동으로 호출된다. 예를 들어, book1을 print 함수에 넣으면, book1이 하나의 문자열(f"{self.title} by {self.author} (ISBN: {self.isbn})")로 출력된다. print() 함수에 객체를 직접 전달할 때 자동으로 호출.
또 만약에 다른 메서드에서 book1을 하나의 문자열로 받고 싶을 때도 쓸 수 있다. 아래 예시처럼, 만약에 __str__ 메서드로 문자열 변환을 따로 안해준다면, book1을 추가할때 return으로 {book1}의 주소값(?)이 반환되는 걸 볼 수 있다.
2. 도서관 클래스
이제 도서관 클래스를 만들자!
class Library:
def __init__(self):
self.books = []
def add_book(self, book):
self.books.append(book)
return f"{book}이 추가되었습니다."
def remove_book(self, isbn):
for book in self.books[:]:
if book.isbn == isbn:
self.books.remove(book)
return f"{book}을 제거합니다."
return "책을 찾을 수 없습니다."
def find_book(self, isbn):
for book in self.books:
if book.isbn == isbn:
return book #f"{book}을 찾았습니다." 이거였는데 멤버 클래스에서 객체 받아오려고 고침.
return None #f"책을 찾을 수 없습니다." 이것도 수정함.
def show_all(self):
if not self.books:
return "도서관에 책이 없습니다."
return "\n".join(str(book) for book in self.books) #Pythonic한 코드
def list_available_books(self):
return [book for book in self.books if book.available]
실수했던 부분. 도서관에 있는 모든 책을 다 출력하는 메서드를 짤 때, allbook이라는 빈 리스트를 하나 더 만들어서 여기서 빼오려고 했다. 그런데 생각해보면 굳이 그럴 필요가? books = [ ] 안에 이미 들어가 있는데ㅋㅋ books 안에서 객체를 하나씩 빼서 str 형태로 만들고 이걸 str 변환한 책들을 담은 리스트에 담아서 뽑아준다. 근데 이렇게 하는 것보다 한 줄로 손쉽게 만드는 법! str(book)으로 만들어준 문자열을 join으로 한방에 합쳐주면 전체 책 리스트가 만들어진다.
def show_all(self):
if not self.books:
return "도서관에 책이 없습니다."
# self.allbook = [] allbook을 생성하는 것은 불필요. 이미 self.books에 모든 책이 저장되어 있기 때문.
# for book in self.books:
# self.allbook.append(book)
# return allbook
return "\n".join(str(book) for book in self.books) #Pythonic한 코드
# book_string= []
# for book in self.books:
# book_string.append(str(book))
# return "\n".join(book_string)
참고로 join( ) 메서드 사용법
lines = ['First line', 'Second line', 'Third line']
result = '\n'.join(lines)
print(result)
# 출력:
# First line
# Second line
# Third line
3. 멤버 클래스
class Member:
def __init__(self, name):
self.name = name
self.borrowed_books = []
def borrow_book(self, library, isbn):
book = library.find_book(isbn)
if book is not None and book.available:
book.available = False
self.borrowed_books.append(book)
return f"{self.name}이 {book}을 빌립니다."
return "책을 빌릴 수 없습니다."
def return_book(self, isbn):
for book in self.borrowed_books:
if book.isbn == isbn:
book.available = True
self.borrowed_books.remove(book)
return f"{self.name}이 {book}을 반납합니다."
return "대출한 책이 아닙니다."
borrow_book 메서드 만들때, book = library.find_book(isbn)을 해서 도서관 클래스에 있는 객체를 불러와서 book에 임시저장한다. book = library.find_book(isbn) 에서 library는 매개변수로 Library 클래스의 인스턴스 객체이다. 이 객체가 library.find_book(isbn)은 find_book 메서드를 실행하고 입력받은 isbn을 전달받아 특정 책을 찾는 역할을 한다. find_book이라는 메서드는 Book 클래스의 객체를 반환하거나, None(책을 찾지 못할 때)을 반환한다. 책을 찾아 객체를 반환하면 이걸 book 변수에 임시저장하여, 그 이후에 활용될 수 있다.
book1 = Book("pythonstudybook", "킹왕짱교수", "123")
book2 = Book("1984", "George Orwell", "456")
book3 = Book("To Kill a Mockingbird", "Harper Lee", "789")
goodlibrary = Library()
goodlibrary.add_book(book1)
goodlibrary.add_book(book2)
goodlibrary.add_book(book3)
goodlibrary.show_all()
member = Member("Bob")
print(member.borrow_book(goodlibrary, "123"))
결과도 잘 나온다!
하하 이정도면.. 다음 단계로 넘어가도 될 것 같다. 모듈로 고고!!