import re
import datetime
import json
available_books = []
borrowed_books = {}
def load_data():
global available_books, borrowed_books
# Load available books
try:
with open("books.txt", "r", encoding="utf-8") as f:
available_books = [line.strip() for line in f if line.strip()]
except FileNotFoundError:
pass
# Load borrowed books
borrowed_books = {}
try:
with open("borrowed_books.txt", "r", encoding="utf-8") as f:
for line in f:
parts = line.strip().split("|")
if len(parts) < 2:
continue
title = parts[0]
borrowed_books[title] = {
"name": parts[1],
"first_name": parts[2] if len(parts) > 2 else "",
"last_name": parts[3] if len(parts) > 3 else "",
"email": parts[4] if len(parts) > 4 else "",
"due": parts[5] if len(parts) > 5 else "",
"emailed": parts[6].lower() == "true" if len(parts) > 6 else False,
}
except FileNotFoundError:
pass
def save_data():
with open("books.txt", "w", encoding="utf-8") as f:
for book in available_books:
f.write(book + "\n")
with open("borrowed_books.txt", "w", encoding="utf-8") as f:
for title, data in borrowed_books.items():
f.write(
"|".join([
title,
data.get("name", ""),
data.get("first_name", ""),
data.get("last_name", ""),
data.get("email", ""),
data.get("due", ""),
str(data.get("emailed", False))
]) + "\n"
)
def generate_email(first, last):
first = re.sub(r"[^a-zA-Z]", "", first).lower()
last = re.sub(r"[^a-zA-Z]", "", last).lower()
if not first and not last:
return ""
return f"{first}.{last}@bourne-grammar.lincs.sch.uk"
def display_menu():
print("\nLibrary Menu")
print("1. View books")
print("2. Borrow a book")
print("3. Return a book")
print("4. Exit")
def view_books():
print("\nAvailable books:")
if available_books:
for i, book in enumerate(available_books, 1):
print(f" {i}. {book}")
else:
print(" None")
print("\nBorrowed books:")
if borrowed_books:
for i, (title, info) in enumerate(borrowed_books.items(), 1):
print(f" {i}. {title} (borrowed by {info['name']}, due {info['due']})")
else:
print(" None")
def borrow_book():
if not available_books:
print("No books available.")
return
view_books()
choice = input("Select book number: ")
if not choice.isdigit():
return
idx = int(choice) - 1
if idx < 0 or idx >= len(available_books):
return
first = input("First name: ")
last = input("Last name: ")
if not first and not last:
print("Name required.")
return
title = available_books.pop(idx)
due = (datetime.date.today() + datetime.timedelta(days=14)).isoformat()
borrowed_books[title] = {
"name": f"{first} {last}".strip(),
"first_name": first,
"last_name": last,
"email": generate_email(first, last),
"due": due,
"emailed": False
}
save_data()
print(f"Borrowed '{title}'")
def return_book():
if not borrowed_books:
print("No borrowed books.")
return
titles = list(borrowed_books.keys())
for i, title in enumerate(titles, 1):
print(f" {i}. {title}")
choice = input("Select book number: ")
if not choice.isdigit():
return
idx = int(choice) - 1
if idx < 0 or idx >= len(titles):
return
title = titles[idx]
del borrowed_books[title]
available_books.append(title)
save_data()
print(f"Returned '{title}'")
load_data()
while True:
display_menu()
choice = input("Choose (1-4): ")
if choice == "1":
view_books()
elif choice == "2":
borrow_book()
elif choice == "3":
return_book()
elif choice == "4":
save_data()
print("Goodbye.")
break