تمرین و پروژه‌های پایتون

ساخت برنامه مدیریت کتابخانه با پایتون؛ پروژه کامل با JSON و سیستم امانت

ساخت برنامه مدیریت کتابخانه با پایتون

🗓 آخرین به‌روزرسانی:

ساخت برنامه مدیریت کتابخانه با پایتون یکی از پروژه‌های بسیار مناسب برای عبور از تمرین‌های ساده و رسیدن به یک برنامه کاربردی چندبخشی است. در این پروژه باید اطلاعات کتاب‌ها را نگه داریم، کتاب جدید ثبت کنیم، وضعیت موجود یا امانت‌داده‌شده را کنترل کنیم، نام امانت‌گیرنده و تاریخ امانت را ذخیره کنیم، کتاب را جست‌وجو یا حذف کنیم و در پایان همه داده‌ها را داخل فایل JSON نگه داریم تا بعد از بسته‌شدن برنامه از بین نروند.

این مقاله چهاردهمین پروژه فاز اول دسته تمرین و پروژه‌های پایتون است. اگر مقاله‌های قبلی مثل مدیریت نمرات دانش‌آموزان با پایتون یا مدیریت هزینه‌های شخصی با پایتون را انجام داده باشید، با ایده ذخیره داده‌های ساختاریافته و ساخت منوی تعاملی آشنا هستید. در این پروژه یک مرحله جلوتر می‌رویم و مفهوم وضعیت یا State را هم به داده‌های هر کتاب اضافه می‌کنیم.

در این پروژه چه چیزی می‌سازیم؟

  • ثبت کتاب جدید با عنوان، نویسنده و ISBN
  • تولید شناسه یکتا برای هر کتاب
  • نمایش همه کتاب‌ها
  • نمایش فقط کتاب‌های موجود
  • نمایش کتاب‌های امانت‌داده‌شده
  • جست‌وجو بر اساس عنوان، نویسنده یا ISBN
  • ثبت امانت کتاب
  • ذخیره نام امانت‌گیرنده
  • ثبت خودکار تاریخ امانت
  • ثبت بازگشت کتاب
  • جلوگیری از امانت‌دادن دوباره یک کتاب
  • جلوگیری از بازگرداندن کتابی که امانت نیست
  • حذف کتاب از سیستم
  • گزارش تعداد کل، موجود و امانت‌داده‌شده
  • ذخیره دائمی اطلاعات در JSON
  • مدیریت فایل JSON خراب یا نامعتبر

چرا پروژه مدیریت کتابخانه برای یادگیری پایتون مفید است؟

این پروژه فقط CRUD ساده نیست. در هر رکورد کتاب چند نوع داده داریم: متن برای عنوان و نویسنده، عدد برای شناسه، Boolean برای وضعیت موجود بودن و تاریخ برای زمان امانت. علاوه بر این، عملیات مختلف باید از قوانین مشخصی پیروی کنند. مثلاً کتابی که قبلاً امانت داده شده نباید دوباره امانت داده شود و کتاب موجود نباید عملیات بازگشت را بپذیرد.

این مدل دقیقاً همان چیزی است که در برنامه‌های واقعی می‌بینیم: داده + قانون کسب‌وکار. یادگیری نحوه جدا کردن این دو بخش، برای پروژه‌های بزرگ‌تر مثل فروشگاه، مدیریت سفارش، سامانه آموزش و سیستم رزرو بسیار مهم است.

ساختار داده هر کتاب

هر کتاب را به شکل یک Dictionary نگه می‌داریم:

{
    "id": 1,
    "title": "Clean Code",
    "author": "Robert C. Martin",
    "isbn": "9780132350884",
    "available": true,
    "borrower": "",
    "borrowed_at": ""
}

زمانی که کتاب امانت داده می‌شود، مقدار available برابر false می‌شود و نام امانت‌گیرنده و تاریخ امانت نیز ثبت خواهند شد.

{
    "id": 1,
    "title": "Clean Code",
    "author": "Robert C. Martin",
    "isbn": "9780132350884",
    "available": false,
    "borrower": "علی رضایی",
    "borrowed_at": "2026-08-11"
}

مرحله اول: ساخت فایل پروژه

یک فایل پایتون با نام زیر بسازید:

library_manager.py

فایل اطلاعات کتابخانه نیز به‌صورت خودکار با نام زیر ایجاد خواهد شد:

library.json

مرحله دوم: وارد کردن ماژول‌ها

import json
from pathlib import Path
from datetime import date

ماژول json برای ذخیره و بارگذاری اطلاعات، Path برای کار تمیزتر با مسیر فایل و date برای ثبت تاریخ امانت استفاده می‌شود. برای یادگیری عمیق‌تر این بخش‌ها می‌توانید آموزش کار با فایل‌های JSON در پایتون و تاریخ و زمان در پایتون با datetime را مطالعه کنید.

مرحله سوم: تعریف فایل داده

DATA_FILE = Path("library.json")

قرار دادن مسیر فایل در یک ثابت باعث می‌شود اگر بعداً بخواهیم نام فایل یا محل ذخیره‌سازی را تغییر دهیم، فقط همین خط را ویرایش کنیم.

مرحله چهارم: بارگذاری اطلاعات کتابخانه

def load_books():
    if not DATA_FILE.exists():
        return []

    try:
        with DATA_FILE.open(
            "r",
            encoding="utf-8",
        ) as file:
            data = json.load(file)
    except (
        json.JSONDecodeError,
        OSError,
    ):
        print(
            "فایل کتابخانه قابل خواندن نیست. "
            "برنامه با لیست خالی شروع شد."
        )
        return []

    return data if isinstance(data, list) else []

اگر فایل هنوز ساخته نشده باشد، یک لیست خالی برمی‌گردانیم. اگر فایل وجود داشته باشد اما JSON آن خراب یا ناقص باشد، برنامه به‌جای Crash شدن، پیام خطا نمایش می‌دهد و با داده خالی ادامه می‌دهد.

مرحله پنجم: ذخیره اطلاعات

def save_books(books):
    with DATA_FILE.open(
        "w",
        encoding="utf-8",
    ) as file:
        json.dump(
            books,
            file,
            ensure_ascii=False,
            indent=2,
        )

گزینه ensure_ascii=False باعث می‌شود عنوان‌ها و نام‌های فارسی داخل فایل JSON به‌صورت خوانا ذخیره شوند.

مرحله ششم: تولید شناسه یکتا

برای هر کتاب یک ID لازم داریم تا عملیات امانت، بازگشت و حذف دقیقاً روی همان کتاب انجام شود.

def next_book_id(books):
    return max(
        (
            book.get("id", 0)
            for book in books
        ),
        default=0,
    ) + 1

استفاده از len(books) + 1 روش مناسبی نیست، چون اگر یک کتاب حذف شود احتمال تکرار ID وجود دارد. در اینجا بزرگ‌ترین شناسه فعلی را پیدا می‌کنیم و یک واحد به آن اضافه می‌کنیم.

مرحله هفتم: ثبت کتاب جدید

def add_book(books):
    title = input(
        "عنوان کتاب: "
    ).strip()

    if not title:
        print(
            "عنوان کتاب نمی‌تواند خالی باشد."
        )
        return

    author = input(
        "نام نویسنده: "
    ).strip()

    if not author:
        print(
            "نام نویسنده نمی‌تواند خالی باشد."
        )
        return

    isbn = input(
        "ISBN (اختیاری): "
    ).strip()

    book = {
        "id": next_book_id(books),
        "title": title,
        "author": author,
        "isbn": isbn,
        "available": True,
        "borrower": "",
        "borrowed_at": "",
    }

    books.append(book)
    save_books(books)

    print(
        f"کتاب با شناسه {book['id']} ثبت شد."
    )

کتاب تازه‌ثبت‌شده به‌صورت پیش‌فرض موجود است؛ بنابراین available برابر True قرار می‌گیرد.

مرحله هشتم: نمایش وضعیت یک کتاب

def book_status(book):
    if book.get("available", True):
        return "موجود"

    return (
        "امانت | "
        f"{book.get('borrower', '-')} | "
        f"{book.get('borrowed_at', '-')}"
    )

این تابع فقط مسئول تولید متن وضعیت است. جدا کردن این منطق باعث می‌شود بتوانیم همان وضعیت را در فهرست کامل، نتایج جست‌وجو و گزارش‌ها دوباره استفاده کنیم.

مرحله نهم: نمایش همه کتاب‌ها

def show_books(books):
    if not books:
        print(
            "هنوز کتابی ثبت نشده است."
        )
        return

    print("\n=== فهرست کتاب‌ها ===")

    for book in books:
        print(
            f"#{book.get('id')} | "
            f"{book.get('title')} | "
            f"{book.get('author')} | "
            f"{book_status(book)}"
        )

مرحله دهم: پیدا کردن کتاب با ID

def find_book_by_id(
    books,
    book_id,
):
    for book in books:
        if book.get("id") == book_id:
            return book

    return None

این تابع در عملیات امانت، بازگشت و حذف استفاده خواهد شد و جلوی تکرار کد را می‌گیرد.

مرحله یازدهم: جست‌وجوی کتاب

جست‌وجو را روی سه فیلد عنوان، نویسنده و ISBN انجام می‌دهیم. از casefold() استفاده می‌کنیم تا جست‌وجوی متن انگلیسی نسبت به حروف بزرگ و کوچک حساس نباشد.

def search_books(books):
    query = input(
        "عنوان، نویسنده یا ISBN: "
    ).strip().casefold()

    if not query:
        print(
            "عبارت جست‌وجو خالی است."
        )
        return

    results = [
        book
        for book in books
        if (
            query
            in book.get(
                "title",
                "",
            ).casefold()
            or query
            in book.get(
                "author",
                "",
            ).casefold()
            or query
            in book.get(
                "isbn",
                "",
            ).casefold()
        )
    ]

    if not results:
        print("کتابی پیدا نشد.")
        return

    show_books(results)

مرحله دوازدهم: امانت دادن کتاب

در این عملیات سه شرط مهم داریم: ID باید عدد باشد، کتاب باید وجود داشته باشد و وضعیت آن باید موجود باشد.

def borrow_book(books):
    value = input(
        "شناسه کتاب: "
    ).strip()

    try:
        book_id = int(value)
    except ValueError:
        print(
            "شناسه باید عدد صحیح باشد."
        )
        return

    book = find_book_by_id(
        books,
        book_id,
    )

    if book is None:
        print("کتاب پیدا نشد.")
        return

    if not book.get(
        "available",
        True,
    ):
        print(
            "این کتاب قبلاً امانت داده شده است."
        )
        return

    borrower = input(
        "نام امانت‌گیرنده: "
    ).strip()

    if not borrower:
        print(
            "نام امانت‌گیرنده نمی‌تواند خالی باشد."
        )
        return

    book["available"] = False
    book["borrower"] = borrower
    book["borrowed_at"] = (
        date.today().isoformat()
    )

    save_books(books)

    print(
        "امانت کتاب با موفقیت ثبت شد."
    )

مرحله سیزدهم: بازگشت کتاب

def return_book(books):
    value = input(
        "شناسه کتاب: "
    ).strip()

    try:
        book_id = int(value)
    except ValueError:
        print(
            "شناسه باید عدد صحیح باشد."
        )
        return

    book = find_book_by_id(
        books,
        book_id,
    )

    if book is None:
        print("کتاب پیدا نشد.")
        return

    if book.get(
        "available",
        True,
    ):
        print(
            "این کتاب در حال حاضر موجود است."
        )
        return

    book["available"] = True
    book["borrower"] = ""
    book["borrowed_at"] = ""

    save_books(books)

    print(
        "بازگشت کتاب ثبت شد."
    )

بعد از بازگشت، اطلاعات امانت‌گیرنده و تاریخ قبلی پاک می‌شوند و کتاب دوباره در وضعیت موجود قرار می‌گیرد.

مرحله چهاردهم: نمایش کتاب‌های موجود و امانت‌شده

def show_available_books(books):
    available = [
        book
        for book in books
        if book.get("available", True)
    ]

    if not available:
        print(
            "در حال حاضر کتاب موجودی نداریم."
        )
        return

    show_books(available)


def show_borrowed_books(books):
    borrowed = [
        book
        for book in books
        if not book.get(
            "available",
            True,
        )
    ]

    if not borrowed:
        print(
            "هیچ کتابی در امانت نیست."
        )
        return

    show_books(borrowed)

مرحله پانزدهم: حذف کتاب

بهتر است کتابی که در امانت است مستقیماً حذف نشود؛ چون با حذف آن اطلاعات امانت هم از بین می‌رود.

def delete_book(books):
    value = input(
        "شناسه کتاب برای حذف: "
    ).strip()

    try:
        book_id = int(value)
    except ValueError:
        print(
            "شناسه باید عدد صحیح باشد."
        )
        return

    book = find_book_by_id(
        books,
        book_id,
    )

    if book is None:
        print("کتاب پیدا نشد.")
        return

    if not book.get(
        "available",
        True,
    ):
        print(
            "کتاب امانت‌داده‌شده را "
            "ابتدا برگردانید."
        )
        return

    confirm = input(
        f"حذف {book['title']}؟ (بله/خیر): "
    ).strip().lower()

    if confirm not in {
        "بله",
        "yes",
        "y",
    }:
        print("حذف لغو شد.")
        return

    books.remove(book)
    save_books(books)

    print("کتاب حذف شد.")

مرحله شانزدهم: گزارش کتابخانه

def library_report(books):
    total = len(books)

    available = sum(
        1
        for book in books
        if book.get("available", True)
    )

    borrowed = total - available

    print("\n=== گزارش کتابخانه ===")
    print(f"کل کتاب‌ها: {total}")
    print(f"موجود: {available}")
    print(f"در امانت: {borrowed}")

این گزارش ساده است، اما مفهوم Aggregation را تمرین می‌دهد؛ یعنی به‌جای مشاهده رکوردها به‌صورت جداگانه، وضعیت کلی داده‌ها را محاسبه می‌کنیم.

مرحله هفدهم: ساخت منوی برنامه

def show_menu():
    print("\n=== مدیریت کتابخانه ===")
    print("1) ثبت کتاب")
    print("2) نمایش همه کتاب‌ها")
    print("3) جست‌وجوی کتاب")
    print("4) امانت کتاب")
    print("5) بازگشت کتاب")
    print("6) کتاب‌های موجود")
    print("7) کتاب‌های امانت‌شده")
    print("8) گزارش کتابخانه")
    print("9) حذف کتاب")
    print("0) خروج")

کد کامل برنامه مدیریت کتابخانه با پایتون

import json
from pathlib import Path
from datetime import date

DATA_FILE = Path("library.json")


def load_books():
    if not DATA_FILE.exists():
        return []

    try:
        with DATA_FILE.open(
            "r",
            encoding="utf-8",
        ) as file:
            data = json.load(file)
    except (
        json.JSONDecodeError,
        OSError,
    ):
        print(
            "فایل کتابخانه قابل خواندن نیست."
        )
        return []

    return data if isinstance(data, list) else []


def save_books(books):
    with DATA_FILE.open(
        "w",
        encoding="utf-8",
    ) as file:
        json.dump(
            books,
            file,
            ensure_ascii=False,
            indent=2,
        )


def next_book_id(books):
    return max(
        (
            book.get("id", 0)
            for book in books
        ),
        default=0,
    ) + 1


def book_status(book):
    if book.get("available", True):
        return "موجود"

    return (
        "امانت | "
        f"{book.get('borrower', '-')} | "
        f"{book.get('borrowed_at', '-')}"
    )


def show_books(books):
    if not books:
        print("کتابی برای نمایش وجود ندارد.")
        return

    print("\n=== فهرست کتاب‌ها ===")

    for book in books:
        print(
            f"#{book.get('id')} | "
            f"{book.get('title')} | "
            f"{book.get('author')} | "
            f"{book_status(book)}"
        )


def find_book_by_id(
    books,
    book_id,
):
    for book in books:
        if book.get("id") == book_id:
            return book

    return None


def add_book(books):
    title = input("عنوان کتاب: ").strip()

    if not title:
        print("عنوان نمی‌تواند خالی باشد.")
        return

    author = input("نام نویسنده: ").strip()

    if not author:
        print("نام نویسنده نمی‌تواند خالی باشد.")
        return

    isbn = input("ISBN (اختیاری): ").strip()

    book = {
        "id": next_book_id(books),
        "title": title,
        "author": author,
        "isbn": isbn,
        "available": True,
        "borrower": "",
        "borrowed_at": "",
    }

    books.append(book)
    save_books(books)

    print(
        f"کتاب با شناسه {book['id']} ثبت شد."
    )


def search_books(books):
    query = input(
        "عنوان، نویسنده یا ISBN: "
    ).strip().casefold()

    if not query:
        print("عبارت جست‌وجو خالی است.")
        return

    results = [
        book
        for book in books
        if (
            query
            in book.get(
                "title",
                "",
            ).casefold()
            or query
            in book.get(
                "author",
                "",
            ).casefold()
            or query
            in book.get(
                "isbn",
                "",
            ).casefold()
        )
    ]

    if not results:
        print("کتابی پیدا نشد.")
        return

    show_books(results)


def borrow_book(books):
    value = input("شناسه کتاب: ").strip()

    try:
        book_id = int(value)
    except ValueError:
        print("شناسه باید عدد صحیح باشد.")
        return

    book = find_book_by_id(books, book_id)

    if book is None:
        print("کتاب پیدا نشد.")
        return

    if not book.get("available", True):
        print(
            "این کتاب قبلاً امانت داده شده است."
        )
        return

    borrower = input(
        "نام امانت‌گیرنده: "
    ).strip()

    if not borrower:
        print(
            "نام امانت‌گیرنده نمی‌تواند خالی باشد."
        )
        return

    book["available"] = False
    book["borrower"] = borrower
    book["borrowed_at"] = (
        date.today().isoformat()
    )

    save_books(books)
    print("امانت کتاب ثبت شد.")


def return_book(books):
    value = input("شناسه کتاب: ").strip()

    try:
        book_id = int(value)
    except ValueError:
        print("شناسه باید عدد صحیح باشد.")
        return

    book = find_book_by_id(books, book_id)

    if book is None:
        print("کتاب پیدا نشد.")
        return

    if book.get("available", True):
        print(
            "این کتاب در حال حاضر موجود است."
        )
        return

    book["available"] = True
    book["borrower"] = ""
    book["borrowed_at"] = ""

    save_books(books)
    print("بازگشت کتاب ثبت شد.")


def show_available_books(books):
    rows = [
        book
        for book in books
        if book.get("available", True)
    ]

    if not rows:
        print("کتاب موجودی نداریم.")
        return

    show_books(rows)


def show_borrowed_books(books):
    rows = [
        book
        for book in books
        if not book.get("available", True)
    ]

    if not rows:
        print("هیچ کتابی در امانت نیست.")
        return

    show_books(rows)


def library_report(books):
    total = len(books)
    available = sum(
        1
        for book in books
        if book.get("available", True)
    )
    borrowed = total - available

    print("\n=== گزارش کتابخانه ===")
    print(f"کل کتاب‌ها: {total}")
    print(f"موجود: {available}")
    print(f"در امانت: {borrowed}")


def delete_book(books):
    value = input(
        "شناسه کتاب برای حذف: "
    ).strip()

    try:
        book_id = int(value)
    except ValueError:
        print("شناسه باید عدد صحیح باشد.")
        return

    book = find_book_by_id(books, book_id)

    if book is None:
        print("کتاب پیدا نشد.")
        return

    if not book.get("available", True):
        print(
            "کتاب امانت‌داده‌شده را "
            "ابتدا برگردانید."
        )
        return

    confirm = input(
        f"حذف {book['title']}؟ (بله/خیر): "
    ).strip().lower()

    if confirm not in {
        "بله",
        "yes",
        "y",
    }:
        print("حذف لغو شد.")
        return

    books.remove(book)
    save_books(books)
    print("کتاب حذف شد.")


def show_menu():
    print("\n=== مدیریت کتابخانه ===")
    print("1) ثبت کتاب")
    print("2) نمایش همه کتاب‌ها")
    print("3) جست‌وجوی کتاب")
    print("4) امانت کتاب")
    print("5) بازگشت کتاب")
    print("6) کتاب‌های موجود")
    print("7) کتاب‌های امانت‌شده")
    print("8) گزارش کتابخانه")
    print("9) حذف کتاب")
    print("0) خروج")


def main():
    books = load_books()

    while True:
        show_menu()

        choice = input(
            "انتخاب شما: "
        ).strip()

        if choice == "1":
            add_book(books)
        elif choice == "2":
            show_books(books)
        elif choice == "3":
            search_books(books)
        elif choice == "4":
            borrow_book(books)
        elif choice == "5":
            return_book(books)
        elif choice == "6":
            show_available_books(books)
        elif choice == "7":
            show_borrowed_books(books)
        elif choice == "8":
            library_report(books)
        elif choice == "9":
            delete_book(books)
        elif choice == "0":
            print("برنامه پایان یافت.")
            break
        else:
            print("گزینه نامعتبر است.")


if __name__ == "__main__":
    main()

نمونه اجرای برنامه

=== مدیریت کتابخانه ===
1) ثبت کتاب
2) نمایش همه کتاب‌ها
3) جست‌وجوی کتاب
4) امانت کتاب
5) بازگشت کتاب
6) کتاب‌های موجود
7) کتاب‌های امانت‌شده
8) گزارش کتابخانه
9) حذف کتاب
0) خروج

انتخاب شما: 1
عنوان کتاب: Clean Code
نام نویسنده: Robert C. Martin
ISBN (اختیاری): 9780132350884
کتاب با شناسه 1 ثبت شد.

نمونه ثبت امانت

شناسه کتاب: 1
نام امانت‌گیرنده: علی رضایی
امانت کتاب ثبت شد.

اگر بعد از آن فهرست را نمایش دهید، وضعیت کتاب به شکل زیر خواهد بود:

#1 | Clean Code | Robert C. Martin | امانت | علی رضایی | 2026-08-11

کد پروژه چگونه بررسی شد؟

قبل از انتشار، ساختار اصلی کد از نظر Syntax بررسی شد و سناریوهای پایه نیز تست شدند: ثبت کتاب جدید، تولید ID، امانت کتاب، جلوگیری از امانت مجدد، بازگشت کتاب، جست‌وجوی عنوان و محاسبه گزارش موجودی. این تست‌ها نشان می‌دهند منطق اصلی پروژه قبل از افزودن قابلیت‌های پیشرفته‌تر درست کار می‌کند.

اشتباه‌های رایج در پروژه مدیریت کتابخانه

استفاده از عنوان به‌عنوان شناسه

ممکن است چند نسخه از یک کتاب یا چند کتاب با عنوان مشابه وجود داشته باشند. استفاده از ID عددی باعث می‌شود هر رکورد مستقل و قابل مدیریت باشد.

نداشتن وضعیت موجودی

اگر فقط نام امانت‌گیرنده را ذخیره کنیم، بررسی وضعیت کتاب سخت‌تر می‌شود. یک Boolean واضح مثل available منطق برنامه را خواناتر می‌کند.

امانت دوباره کتاب

قبل از تغییر وضعیت باید بررسی کنیم کتاب در حال حاضر موجود باشد. همین کنترل ساده از ناسازگاری داده جلوگیری می‌کند.

حذف کتاب در حال امانت

حذف کتابی که هنوز نزد امانت‌گیرنده است باعث از بین رفتن سابقه مهم می‌شود. در این پروژه ابتدا بازگشت کتاب اجباری است.

ذخیره نکردن بعد از عملیات

بعد از ثبت، امانت، بازگشت یا حذف باید فایل JSON دوباره نوشته شود؛ در غیر این صورت تغییرات فقط در حافظه باقی می‌مانند.

چطور پروژه را حرفه‌ای‌تر کنیم؟

  1. تاریخ سررسید: هنگام امانت یک Due Date مثلاً هفت یا چهارده روز بعد تعیین کنید.
  2. کتاب‌های دیرکرد: کتاب‌هایی را که از تاریخ بازگشتشان گذشته نمایش دهید.
  3. تاریخچه امانت: به‌جای پاک کردن اطلاعات امانت بعد از بازگشت، آن را در یک لیست History نگه دارید.
  4. مدیریت اعضا: اعضا را با ID، نام و اطلاعات تماس در فایل جداگانه نگه دارید.
  5. تعداد نسخه: یک عنوان بتواند چند نسخه فیزیکی داشته باشد.
  6. جریمه دیرکرد: بر اساس تعداد روز تأخیر مبلغ جریمه محاسبه کنید.
  7. ویرایش کتاب: امکان اصلاح عنوان، نویسنده یا ISBN را اضافه کنید.
  8. مرتب‌سازی: فهرست را بر اساس عنوان، نویسنده یا وضعیت مرتب کنید.
  9. خروجی CSV: گزارش موجودی را برای Excel خروجی بگیرید.
  10. SQLite: در نسخه پیشرفته JSON را با دیتابیس جایگزین کنید.
  11. OOP: کلاس‌های Book، Member و Library بسازید.
  12. رابط گرافیکی: نسخه Tkinter با جدول کتاب‌ها و فرم امانت طراحی کنید.

تمرین پیشنهادی: اضافه کردن تاریخ سررسید

در زمان امانت، علاوه بر borrowed_at یک فیلد جدید به نام due_date ذخیره کنید. می‌توانید با timedelta تاریخ هفت روز بعد را محاسبه کنید:

from datetime import date, timedelta

borrowed_at = date.today()
due_date = borrowed_at + timedelta(days=7)

سپس در گزارش امانت‌ها مشخص کنید کدام کتاب‌ها از تاریخ سررسید عبور کرده‌اند.

تمرین پیشرفته: تبدیل به OOP

بعد از اینکه نسخه تابع‌محور پروژه را کامل اجرا کردید، آن را به طراحی شی‌گرا تبدیل کنید. کلاس Book می‌تواند اطلاعات یک کتاب را مدیریت کند و کلاس Library مسئول ثبت، جست‌وجو، امانت، بازگشت و ذخیره داده‌ها باشد. پروژه مدیریت مخاطبان با JSON و OOP نمونه مناسبی برای دیدن ساختار یک پروژه شی‌گرا و چندعملیاتی است.

این پروژه چه مفاهیمی را تمرین می‌دهد؟

  • List و Dictionary
  • Boolean و مدیریت State
  • JSON
  • Pathlib
  • date و datetime
  • خواندن و نوشتن فایل
  • توابع و مقدار بازگشتی
  • حلقه for و while
  • شرط‌ها
  • Exception Handling
  • List Comprehension
  • Generator Expression
  • جست‌وجو و فیلتر داده
  • اعتبارسنجی ورودی
  • مدیریت قوانین کسب‌وکار
  • گزارش‌گیری و Aggregation
  • ماندگاری اطلاعات

جمع‌بندی

در این آموزش یک برنامه کامل مدیریت کتابخانه با پایتون ساختیم که می‌تواند کتاب جدید ثبت کند، اطلاعات را جست‌وجو کند، وضعیت موجود یا امانت را مدیریت کند، نام امانت‌گیرنده و تاریخ را ذخیره کند، بازگشت کتاب را ثبت کند، گزارش موجودی بسازد و همه اطلاعات را داخل فایل JSON نگه دارد.

مهم‌ترین نکته این پروژه، مدیریت صحیح State است. کتاب فقط یک مجموعه متن نیست؛ در هر لحظه یک وضعیت مشخص دارد و عملیات بعدی بر اساس همان وضعیت مجاز یا غیرمجاز می‌شوند. این مفهوم پایه بسیاری از برنامه‌های واقعی است. بعد از تکمیل نسخه فعلی، افزودن تاریخ سررسید و تاریخچه امانت بهترین مسیر برای توسعه پروژه خواهد بود.

📌 همچنین بخوانید: تمرین پایتون با جواب، ساخت بازی با پایتون و Pygame و ساخت ربات با پایتون

می‌خواهی پیشرفتت ذخیره شود؟با ورود یا ثبت‌نام رایگان، درس‌های تمام‌شده را علامت بزن و درصد پیشرفتت را در حساب کاربری ببین.ورود / ثبت‌نام برای ذخیره پیشرفت
درس بعدی · پروژه‌های پایتون (15 از 19)ساخت برنامه مدیریت موجودی فروشگاه با پایتون؛ پروژه کامل با JSON و گزارش انبار ←
آموزش‌های تازه، کد آماده و رفع خطاهر هفته در کانال Dev Source؛ رایگان.
🧭 مسیر یادگیری پایتون از صفر
ماژول 10: جمع‌بندی و پروژه پایانی — درس 44 از 44

برای ذخیره پیشرفت در همه دستگاه‌ها و دریافت گواهی پایان مسیر، رایگان ثبت‌نام کن یا وارد شو.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *