راه
۴ کیو· سختپیشرفتهPYTHON۴ ثانیه · ۲۵۶ مگابایت

کتابخانه‌ی برهم

داور به اینترنت دسترسی ندارد؛ یک سرور کتابخانه‌ی آزمایشی با همان سه نشانی صورت سؤال جای آن جواب می‌دهد (بالای کدت آمده). اطلاعات کتاب را با requests.post(url, json=book) بفرست.

برنامه‌نویس جدید کتابخانه به این کتابخانه‌ی آنلاین در تمرین کتابخانه‌ی درهم نظم داده و هر بخش را با یک آدرس (URL) مشخص کرده‌است که می‌توان از روی آن، دسته‌بندی بخش موردنظر را تشخیص داد. دقت کنید که کتاب‌های هر بخش فقط شامل یک موضوع هستند.

📐 ریاضی: http://127.0.0.1:8000/mathematics/ ⚛️ فیزیک: http://127.0.0.1:8000/physics/ ♟️ شطرنج: http://127.0.0.1:8000/chess/

اکنون شما باید تابعی به نام add_book طراحی کنید که با گرفتن ورودی book که شامل اطلاعات یک کتاب است، بررسی کند آیا book در بخش مربوطه‌ی خود از قبل وجود دارد یا خیر. اطلاعات یک کتاب در قالب یک دیکشنری به‌صورت زیر است:

json
{"name": "book_name", "category": "book_category"}

🔹 شرایط تابع add_book

❌ شرط ۱: دسته‌بندی نامعتبر

اگر category جزو موضوعات موجود نبود، باید عبارت Invalid Category را برگرداند.

❌ شرط ۲: کتاب تکراری

اگر book در بخش مربوطه از قبل وجود داشت، تابع باید عبارت Bad Request را برگرداند.

✅ شرط ۳: افزودن کتاب جدید

در غیر این صورت، تابع باید با استفاده از متد POST کتابخانه‌ی requests، اطلاعات کتاب (book) را به آدرس مربوط به آن بخش ارسال کند.

⚠️ شرط ۴: خطا در دسترسی

اگر نتوانستید به اطلاعات موجود در آدرس آن بخش دسترسی پیدا کنید نیز باید عبارت Bad Request را برگردانید.


📖 مثال

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

python
book = {"name": "Fermat's Last Theorem", "category": "mathematics"}

با توجه به این‌که مقدار category این کتاب mathematics (ریاضی) است، در ابتدا تابع باید بررسی کند که آیا این کتاب در آدرس بخش ریاضی (یعنی http://127.0.0.1:8000/mathematics/) وجود دارد یا خیر؛ سپس یکی از کارهای زیر را انجام دهد:

  • اگر کتاب در بخش ریاضی از قبل موجود باشد، عبارت Bad Request را برگرداند
  • در غیر این صورت، اطلاعات کتاب (data) را با استفاده از متد POST به آدرس بخش ریاضی (http://127.0.0.1:8000/mathematics/) ارسال کند

📖 راهنمایی

💡 لیست کتاب‌ها را چطور پیدا کنم؟

اگر آدرس مربوط به دسته‌بندی متناسب با کتاب ورودی در متغیر url قرار گرفته باشد، با استفاده از متد get به‌صورت زیر می‌توانیم اطلاعات موجود در آن آدرس را دریافت کنیم.

دقت کنید از آن‌جا که اطلاعات موجود در هر قسمت از کتابخانه به‌صورت JSON است، با استفاده از متد json روی شیء پاسخ (response) می‌توانیم آن را به ساختار پایتونی معادل با آن تبدیل کنیم.

python
import requests

response = requests.get(url)
books_list = response.json()

💡 چه‌طور به اطلاعات هر کتاب دسترسی پیدا کنم؟

خروجی متد json فراخوانی‌شده بر روی شیء پاسخ (response)، یک لیست شامل چندین دیکشنری است که هر دیکشنری نشان‌دهنده‌ی اطلاعات یک کتاب است. با پیمایش بر روی این لیست می‌توانید به اطلاعات هر کتاب به‌صورت جداگانه دسترسی پیدا کنید.

💡 اطلاعات کتاب را چه‌طور بفرستم؟

اگر اطلاعات مربوط به کتاب ورودی در متغیر book و آدرس متناسب با آن در متغیر url قرار گرفته باشد، با استفاده از متد post به‌صورت زیر می‌توانیم اطلاعات موجود را به آدرس متناسب با آن ارسال کنیم:

از آن‌جا که اطلاعات کتاب از نوع دیکشنری است، می‌توانیم آن را با استفاده از آرگومان json ارسال کنیم.

python
import requests

requests.post(url, json=book)

دقت کنید که آدرس‌ URL هر بخش را کامل و صحیح بنویسید. در غیر این صورت با خطا مواجه می‌شوید. حتماً حواستان باشد که در انتهای آدرس url علامت / قرار دهید.


✅ پاسخ نهایی

python
import requests

def add_book(book):
    # تعیین آدرس بر اساس دسته‌بندی
    category = book.get("category")
    if category == "mathematics":
        url = "http://127.0.0.1:8000/mathematics/"
    elif category == "physics":
        url = "http://127.0.0.1:8000/physics/"
    elif category == "chess":
        url = "http://127.0.0.1:8000/chess/"
    else:
        return "Invalid Category"

    try:
        # دریافت لیست کتاب‌های موجود
        response = requests.get(url, timeout=5)
        if response.status_code != 200:
            return "Bad Request"

        books_list = response.json()

        # بررسی وجود کتاب تکراری
        for existing_book in books_list:
            if existing_book.get("name") == book.get("name"):
                return "Bad Request"

        # ارسال کتاب جدید
        response_post = requests.post(url, json=book, timeout=5)
        if response_post.status_code != 201 and response_post.status_code != 200:
            return "Bad Request"

        return response_post.json()

    except:
        return "Bad Request"

📄 main.py


📖 توضیح کد

  • تعیین آدرس: بر اساس مقدار category، آدرس مناسب انتخاب می‌شود. اگر دسته‌بندی نامعتبر باشد، "Invalid Category" برگردانده می‌شود.
  • دریافت لیست کتاب‌ها: با requests.get(url) لیست کتاب‌های موجود دریافت می‌شود
  • بررسی تکراری بودن: با پیمایش لیست کتاب‌ها، اگر کتابی با نام مشابه وجود داشته باشد، "Bad Request" برگردانده می‌شود
  • ارسال کتاب جدید: با requests.post(url, json=book) کتاب جدید ارسال می‌شود
  • مدیریت خطاها: هر گونه خطا (اتصال، JSON نامعتبر، timeout) با try-except گرفته شده و "Bad Request" برگردانده می‌شود

🚀 پس از تکمیل تابع، می‌توانید آن را با تست‌های مختلف امتحان کنید و مطمئن شوید که همه‌ی حالات را پوشش می‌دهد.

نمونه‌ها

ورودی نمونه ۱
result = add_book({"name": "Linear Algebra", "category": "mathematics"})
[book["name"] for book in library["mathematics"]]
خروجی نمونه ۱
["Fermat's Last Theorem", 'Linear Algebra']
ورودی نمونه ۲
add_book({"name": "Fermat's Last Theorem", "category": "mathematics"})
len(library["mathematics"])
خروجی نمونه ۲
'Bad Request'
1
ورودی نمونه ۳
add_book({"name": "The Selfish Gene", "category": "biology"})
[len(books) for books in library.values()]
خروجی نمونه ۳
'Invalid Category'
[1, 1, 0]
ورودی نمونه ۴
down.add("chess")
add_book({"name": "My System", "category": "chess"})
library["chess"]
خروجی نمونه ۴
'Bad Request'
[]
ورودی نمونه ۵
result = add_book({"name": "Linear Algebra", "category": "physics"})
result = add_book({"name": "My System", "category": "chess"})
[[book["name"] for book in library[key]] for key in ("physics", "chess")]
خروجی نمونه ۵
[['The Road to Reality', 'Linear Algebra'], ['My System']]

برای نوشتن پاسخ و دریافت امتیاز، ابتدا وارد حساب شوید.

ورود