فرض کنید که در یک فایل پایتون چند کلاس وجود دارد و به مجموعه کل آن‌ کلاس‌ها \(S\) می‌گوییم. گراف جهت دار \(G\) را از روی مجموعه \(S\) به این شکل می‌سازیم که راس \(v\) به راس \(u\) یال دارد اگر و فقط اگر کلاس \(v\) از کلاس \(u\) به صورت مستقیم ارث برده باشد. برای مثال به کد زیر دقت کنید:

class A:
    def f(self, a, b):
    	return a + b

class B(A):
    def g(self, a):
    	return a*10

class C(A):
    def g(self, a):
    	return a**2

class D(C, B):
    pass

گراف کلاس‌های بالا:

مثل

در این مثال \(B\) و \(C\) از \(A\) ارث برده‌است و کلاس \(D\) هم از کلاس \(C\) و \(B\) ارث برده است.

حال کد زیر را در نظر بگیرید

d = D()
print(d.f(10, 20)) # 30

کلاس C و B تابع f را از کلاس A به ارث برده‌اند و کلاس D این تابع را از این دو کلاس به ارث برده‌است. پس دو مسیر D-B-A و D-C-A برای صدا شدن تابع f قابل تصور است که در این سوال (مانند قانون خود مفسر پایتون) در ارث‌بری کلاسی که زودتر (چپ‌تر در پرانتز جلوی تعریف کلاس) نوشته شده را مقدم در نظر می‌گیریم. یعنی مسیر D-C-A را برای d.f در نظر می‌گیریم.

در کد زیر برای مثال:

d = D()
print(d.g(20)) # 400

در اینجا تابع g هم در کلاس B و هم در کلاس C وجود دارد ولی طبق مفسر پایتون، مسیر مورد نظر در این سوال، مسیر D-C برای d.g است.

حال لیست کلاس‌ها در اختیار شما قرار می‌گیرد و شما باید با ایجاد تغییراتی در کلاس‌ها شرایطی را ایجاد کنید که با صدا کردن هر تابع. مسیر صدا شدن آن تابع در شی کلاس Record که به شما ورودی داده می‌شود ذخیره شود.

این کار در قالب یک تابع به نام rearrange(ls, rec) باید صورت بگیرد که ls لیست کلاس‌هاست و rec آن شی مورد نظر از کلاس Record هست که باید مسیرها در آن ذخیره شود.

  • تضمین می‌شود قبل از صدا کردن هر تابع مسیر rec خالی شود.
  • تضمین می‌شود هیچ کلاسی از دو کلاسی که از هم ارث برده‌اند به صورت مستقیم ارث نبرد.
  • تضمین می‌شود هیچ کلاسی از کلاسی بیرون از لیست داده شده جز object ارث نبرد.
  • دقت کنید که ممکن است توابع تعریف شده همدیگر را صدا کنند (و این جزو مسیر به شمار نمی‌آید).

برای درک بهتر به کد زیر و خروجی آن دقت کنید.

نمونه

from record import Record
from solution import rearrange # your implemented function

class A:
    def f(self, a, b):
    	return a + b

class B(A):
    def g(self, a):
    	return a*10

class C(A):
    def g(self, a):
    	return a**2

class D(C, B):
    pass

rec = Record()
rearrange([A, B, C, D], rec)
d = D()
print(d.f(10, 20))
print(rec.get_path_list())

خروجی کد بالا:

30
[<class '__main__.D'>, <class '__main__.C'>, <class '__main__.A'>]

کلاس Record

این کلاس در کنار فایل ارسالی شما قرار می‌گیرد (نیازی به ارسال این فایل نیست) و شما می‌توانید آن را import کنید. این کلاس دارای سه تابع زیر است:

  • تابع add_node(node): این تابع یک عضو گرفته (که در این سوال باید یک کلاس باشد) و آن را به لیست مسیر اضافه می‌کند.
  • تابع get_path_list(): این تابع لیست مسیر را خروجی می‌دهد.
  • تابع refresh(): این تابع مسیر ذخیره شده را خالی می‌کند.

نکات

  • می‌توانید فایل اولیه این سوال را از این لینک دریافت کنید.
  • این سوال دارای ۴ تست است که ۲ تست آن یک مسیر ساده، یک تست گرافی مانند گراف مثال زده شده و تست دیگر یک گراف پیچیده می‌باشد. اگر برای مثال فقط برای مسیرها حل کردید جواب خود را ارسال کنید، بخشی از نمره به شما تعلق می‌گیرد.
  • در صورت تمایل، می‌توانید علاوه‌بر تابع خواسته‌شده، کلاس‌ها و تابع‌های کمکی دیگری نیز در فایل solution.py پیاده‌سازی کنید.

نحوه ارسال

شما باید تابع rearrange موجود در فایل solution.py را تکمیل و سپس این فایل را ارسال کنید.

ارسال پاسخ برای این سؤال
فایلی انتخاب نشده است.