728x90
반응형
도서 대출 기능
우선 도서를 대출 하는 과정을 상상해 보면, 조회해서 어떤 책들이 있는지 알고 있는 상태이다.
그런데 한권만 대출하나 ? 여러권도 가능할 것이다.
, 로 구분 지어서 입력 받아서 리스트에 저장한뒤에 리스트에서 쭉 for 문을 돌려서 실행 시키도록 해보자
# 입력 받는 부분 테스트 해보기
def lend_book():
connection = psycopg2.connect(host=DATABASE_HOST, user=DATABASE_USER, password=DATABASE_PASSWORD,
dbname=DATABASE_NAME, port=DATABASE_PORT)
cursor = connection.cursor()
input_ids = input("대출할 책의 id 들을 (,)로 구분하여 입력해주세요 :")
print(input_ids.split(","))
# 대출할 책의 id 들을 (,)로 구분하여 입력해주세요 :1,2,4,15,2,24,3,4
# ['1', '2', '4', '15', '2', '24', '3', '4']
공백을 처리해야할 필요성이 생김, 하지만 책 이름에도 공백이 있을 수 있다는 것을 명심
[python] 파이썬 공백 제거 (replace, strip) 2가지 방법
lend_book() 기능
def lend_book():
connection = psycopg2.connect(host=DATABASE_HOST, user=DATABASE_USER, password=DATABASE_PASSWORD,
dbname=DATABASE_NAME, port=DATABASE_PORT)
cursor = connection.cursor()
# input_ids = input("대출할 책의 id 들을 (,)로 구분하여 입력해주세요 :")
# print(input_ids.split(","))
# book_ids = []
while True:
lend_option = lend_book_option()
# 도서 ID를 입력받아 해당 글자가 들어간 제목을 가진 도서 모두 조회
if lend_option == 1:
book_ids = [] # 최종 작업할 리스트
try:
input_ids = input("대출할 책의 정확한 ID를 (,)로 구분하여 입력해주세요 :")
split_input = input_ids.split(",") # ,로 구분 짓기
for id in split_input: # 돌면서
if id.strip() != "": # 공백만 있는거 제거
book_ids.append(int(id.strip())) # 제목에 양쪽 끝 공백 제거 후 담기
except ValueError:
print("\\n값을 잘못 입력했습니다.\\n")
continue
print(book_ids)
# 담긴 제목으로 전부 SQL 작업 시작
for input_book_id in book_ids:
# 우선 해당 제목의 책이 있는지 조회
cursor.execute("""SELECT * FROM books WHERE book_id = %s;""", (input_book_id,))
row = cursor.fetchone()
if row == None: # 혹시 입력한 정보로 찾을 수 없을 경우 돌아가게끔 처리
print("\\n")
print("\\n")
print(f"\\n해당 ID({input_book_id})를 가진 도서는 찾을 수 없습니다.")
print("다시 검색해 주세요.\\n")
continue
# 해당 책의 is_available 이 True 면
if row[4]:
loan_date = date.today()
try:
# loans 테이블에 삽입
cursor.execute("""INSERT INTO loans (book_id, loan_date) VALUES (%s, %s);""",
(input_book_id, loan_date,))
# books 테이블에 is_available 을 FALSE 로 변경
cursor.execute("""UPDATE books SET is_available = FALSE WHERE book_id = %s;""",
(input_book_id,))
print(f"{row[1]}, 대출 성공")
connection.commit()
except: # 양쪽에 작업을 해야하니 에러 발생시 돌리기
connection.rollback()
else:
print(f"\\n책 번호 : {row[0]}, 책 제목 :{row[1]}, 현재 대출 가능한 도서가 아닙니다.\\n")
next_action = str(input("다음 작업이 있습니까? [Y/N] :"))
if next_action.upper() == "Y":
lend_book() # 재귀
elif next_action.upper() == "N":
# 다음 작업이 없이 프로그램이 종료될테니 데이터베이스와 연결 종료
print("DB close executed")
cursor.close()
connection.close()
print("DB close done")
raise ExitProgram
else:
print("\\n")
print("잘못 입력하셨습니다. 도서 검색 옵션으로 되돌아 갑니다.")
print("\\n")
# 대출 중인 모든 목록 조회
elif lend_option == 2:
cursor.execute("""
SELECT * FROM books WHERE is_available = FALSE ORDER BY book_id;
""")
rows = cursor.fetchall()
print("\\n현재 모든 도서 정보:")
print("------------------------------------------------------------------")
print(" ID | title | Author | Publisher | Availability |")
print("------------------------------------------------------------------")
for row in rows: # 아직 꾸미지 않은 상태
print(row)
print("\\n")
next_action = str(input("다음 작업이 있습니까? [Y/N] :"))
if next_action.upper() == "Y":
lend_book()
elif next_action.upper() == "N":
# 다음 작업이 없이 프로그램이 종료될테니 데이터베이스와 연결 종료
print("DB close executed")
cursor.close()
connection.close()
print("DB close done")
raise ExitProgram
elif lend_option == 0:
print("\\n")
print("이전 페이지로 돌아갑니다.")
print("\\n")
# 다음 작업이 없이 메인으로 돌아가니 데이터베이스와 연결 종료
print("DB close executed")
cursor.close()
connection.close()
print("DB close done")
raise ReturnToMainMenu
도서 반납 기능
도서 받납의 순서는 유저가 도서를 가져오면 해당정보(book_id) 를 입력받아서 books 와 loans 에 값을 업데이트 하면 끝이다.
def return_book():
connection = psycopg2.connect(host=DATABASE_HOST, user=DATABASE_USER, password=DATABASE_PASSWORD,
dbname=DATABASE_NAME, port=DATABASE_PORT)
cursor = connection.cursor()
print("도서를 반납합니다.\\n")
try:
book_ids = []
return_book_id = input("가져온 도서의 ID를 (,)로 구분하여 입력해주세요 :")
split_input = return_book_id.split(",") # ,로 구분 짓기
for id in split_input: # 돌면서
if id.strip() != "": # 공백만 있는거 제거
book_ids.append(int(id.strip())) # 제목에 양쪽 끝 공백 제거 후 담기
for return_id in book_ids:
cursor.execute("""SELECT * FROM books WHERE book_id = %s AND is_available = FALSE;""", (return_id,))
row = cursor.fetchone()
if row == None: # 혹시 입력한 정보로 찾을 수 없을 경우 돌아가게끔 처리
print(f"\\n해당 ID({return_id})를 가진 도서는 반납예정 데이터에 없습니다.")
print("다시 검색해 주세요.\\n")
continue
if row[0]:
return_date = date.today()
try:
# is_available 다시 True 로 돌려놓기
cursor.execute("""UPDATE books SET is_available = TRUE WHERE book_id = %s;""", (return_id,))
# loans 에 return_date 추가하기
cursor.execute("""UPDATE loans SET return_date = %s WHERE book_id = %s;""",
(return_date, return_id,))
connection.commit()
print(f"{row[1]}, 반납 성공")
except:
connection.rollback()
print("DB close executed")
cursor.close()
connection.close()
print("DB close done")
return
else:
print(f"\\n책 번호 : {row[0]}, 책 제목 :{row[1]}, 현재 반납 가능한 도서가 아닙니다.\\n")
except ValueError:
print("\\n잘못된 정보를 입력하셨습니다.")
print("DB close executed")
cursor.close()
connection.close()
print("DB close done")
return
대출중인 도서를 모두 조회하는 기능
기존에 있던 대출 도서 조회 기능에 LEFT 조인으로 값을 가져오는 형태로 구현해보았다.
# 대출 중인 모든 목록 조회
elif lend_option == 2:
cursor.execute("""SELECT b.*, l.loan_id, l.loan_date, l.return_date FROM books AS b LEFT JOIN loans AS l ON b.book_id = l.book_id WHERE b.is_available = FALSE AND l.return_date IS NULL;""")
rows = cursor.fetchall()
print("\\n현재 대출중인 모든 도서 정보입니다.")
print(
"------------------------------------------------------------------------------------------------------------")
print(
"| Book ID | title | Author | Publisher | Availability | LoanID | Taken Date | Return Date |")
print(
"------------------------------------------------------------------------------------------------------------")
if len(rows) == 0:
print("\\n현재 대출중인 도서가 없습니다.\\n")
else:
for row in rows: # 아직 꾸미지 않은 상태
print(row)
print("\\n")
next_action = str(input("다음 작업이 있습니까? [Y/N] :"))
if next_action.upper() == "Y":
lend_book()
elif next_action.upper() == "N":
# 다음 작업이 없이 프로그램이 종료될테니 데이터베이스와 연결 종료
print("DB close executed")
cursor.close()
connection.close()
print("DB close done")
raise ExitProgram
도서 입력 기능에 CSV 파일로 입력할 수 있게 만들기
pyhton 에서 제공하는 라이브러리인 csv, tkinter 를 이용하여 파일 선택 팝업창을 띄우고 csv 파일을 읽어와 “,” 로 구분지에 데이터를 삽입시켜주는 과정
import csv
import tkinter
from tkinter import filedialog
# ....
def insert_book(): # 파일로 추가하는 부분은 나중에
connection = create_connection()
cursor = create_cursor(connection)
while True:
insert_option = insert_book_option()
if insert_option == 1:
print("새로운 도서를 추가합니다.\\n")
title = input("도서 제목을 입력하세요 : ")
author = input("저자를 입력하세요 : ")
publisher = str(input("출판사를 입력하세요 : "))
# query = """INSERT INTO books (title, author, publisher) VALUES (%s, %s, %s);"""
# values = (title, author, publisher,)
try:
cursor.execute("""INSERT INTO books (title, author, publisher) VALUES (%s, %s, %s);""",
(title, author, publisher,))
# cursor.execute(query, values)
connection.commit()
except:
connection.rollback()
print("\\n에러 발생, 작업을 롤백합니다.\\n")
disconnect_db(connection, cursor)
return
elif insert_option == 2:
print("새로운 도서를 csv 파일로 추가합니다.\\n")
root = tkinter.Tk()
root.withdraw()
csv_file = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv")])
if csv_file:
try:
with open(csv_file,'r', newline='') as file:
csv_data = csv.reader(file)
next(csv_data)
for row in csv_data:
if len(row) == 1:
data = row[0].split(",")
title, author, publisher = data[0].strip(), data[1].strip(), data[2].strip()
cursor.execute("""INSERT INTO books (title, author, publisher) VALUES (%s, %s, %s);""",
(title, author, publisher,))
connection.commit()
else:
print(f"\\n데이터 형식 오류, row:{row}")
except Exception as e:
connection.rollback()
print(f"에러가 발생하였습니다. message : {str(e)}")
disconnect_db(connection, cursor)
continue
else:
print("\\n파일이 선택되지 않았습니다.")
disconnect_db(connection, cursor)
continue
elif insert_option == 0:
print("\\n이전 페이지로 돌아갑니다.\\n")
# 다음 작업이 없이 메인으로 돌아가니 데이터베이스와 연결 종료
disconnect_db(connection, cursor)
raise ReturnToMainMenu
# print("\\n도서가 추가되었습니다.\\n")
# disconnect_db(connection, cursor)
728x90
반응형
'Dev. > Python' 카테고리의 다른 글
Python: enumerate, zip, sorted (0) | 2023.10.20 |
---|---|
Python : functools.cmp_to_key() (0) | 2023.10.17 |
Python - Mini project : Library Management System 3 (0) | 2023.07.20 |
Python - Mini project : Library Management System 2 (1) | 2023.07.19 |
Python - Mini project : Library Management System 1 (0) | 2023.07.19 |
댓글