کلاس WorkPlace
استثنای
WorkPlaceIsFull، کلاسConstsو کلاسWorkPlaceرا در همین یک فایل بنویس. داور برای آزمودن متدهای خالی (calc_capacity،calc_costs) زیرکلاسهای کوچکی میسازد؛ نیازی به فایلwork_place.pyنیست.
پس از پیادهسازی کلاس بنیادین Person، اکنون نوبت به کلاس دیگری از موجودیتهای اصلی مدل ما، یعنی کلاس WorkPlace (محل کار)، میرسد. این کلاس نقش مدلسازی مکانهایی را دارد که افراد در آنها مشغول به کار میشوند. کلاس WorkPlace ویژگیها و رفتارهای مشترک انواع مختلف محل کار (مانند معدن، مدرسه و شرکت) را تعریف میکند و مانند کلاس Person، پایهای برای زیرکلاسهای خود خواهد بود.
کد کلاس WorkPlace در فایل work_place.py قرار خواهد گرفت.
استثنای سفارشی WorkPlaceIsFull
قبل از شروع به پیادهسازی کلاس WorkPlace، یک استثنای سفارشی به نام WorkPlaceIsFull تعریف میکنیم. این استثنا برای مدیریت حالتی استفاده میشود که سعی در استخدام فرد در یک محل کار با ظرفیت کامل داشته باشیم. این یک کلاس ساده است که از کلاس پایه Exception ارثبری میکند و صرفاً یک پیام خطا را برمیگرداند.
class WorkPlaceIsFull(Exception):
def __str__(self):
return "work place is full!"
ثابتهای پروژه: کلاس Consts
در طول پروژه، از مقادیر ثابتی مانند قیمتهای پایه برای محاسبهی هزینهها استفاده میکنیم. برای سازماندهی این مقادیر، یک کلاس ساده به نام Consts تعریف میشود که این مقادیر ثابت را در خود نگه میدارد. بخشی از این کلاس که مربوط به قیمتهای پایه ساخت محل کار است، بهصورت زیر تعریف میشود. برخی از این ثابتها را در این قسمت نیاز نداریم و در بخشهای بعدی استفاده میشوند.
class Consts:
BASE_PRICE = {'mine': 150, 'school': 100, 'company': 90}
BASE_PLACE_COST = 2500
LEVEL_MUL = 50
کلاس WorkPlace
instances: یک متغیر کلاس است که لیستی از تمام اشیاءWorkPlaceرا که تاکنون ایجاد شدهاند، نگهداری میکند. هر شیء جدیدWorkPlaceهنگام ساخت به این لیست اضافه میشود.name: نام محل کار است و از نوع رشته است.level: سطح فعلی محل کار است. از نوع عدد صحیح است و با مقدار اولیهی ۱ شروع میشود.expertise: نوع تخصص محل کار (مانند"mine"،"school"و"company") است. از نوع رشته است و با مقدار اولیهی""(رشته خالی) شروع میشود و در زیرکلاسها مقداردهی میشود.employees: لیستی از اشیاءPersonکه در این محل کار مشغول هستند. با لیست خالی[]شروع میشود.capacity: حداکثر تعداد افرادی که میتوانند در این محل کار مشغول باشند. از نوع عدد صحیح است، با مقدار اولیهی ۱ شروع میشود و با ارتقاء سطح بهروزرسانی میشود.
متد سازنده: init(self, name)
- پارامتر
nameبرای مقداردهی ویژگیnameشیء استفاده میشود.- ویژگی
levelبا مقدار1،expertiseبا""،employeesبا[]وcapacityبا1مقداردهی اولیه میشوند.- شیء
selfبه لیستWorkPlace.instancesاضافه میشود تا ردیابی تمام محلهای کار امکانپذیر باشد.متد get_price(self)
این متد هزینهی ساخت این محل کار را بر اساس نوع تخصص آن (
self.expertise) از دیکشنریBASE_PRICEدر کلاسConstsبرمیگرداند.متد upgrade(self)
این متد سطح محل کار (
self.level) را یک واحد افزایش میدهد. پس از افزایش سطح، متدself.calc_capacity()را فراخوانی میکند تا ظرفیت محل کار بر اساس سطح جدید محاسبه و بهروزرسانی شود.متد hire(self, person)
این متد مسئول استخدام یک فرد (
personکه یک شیءPersonاست) در این محل کار است. قبل از استخدام، ظرفیت فعلی محل کار (self.capacity) با تعداد کارمندان فعلی (len(self.employees)) مقایسه میشود. اگر محل کار پر باشد (تعداد کارمندان بیشتر یا مساوی ظرفیت)، استثنایWorkPlaceIsFullرخ میدهد (raiseWorkPlaceIsFull()). در غیر این صورت، شیءpersonبه لیستself.employeesاضافه میشود و ویژگیwork_placeشیءpersonبرابر با این محل کار قرار داده میشود تا فرد به محل کار متصل شود.متد calc_capacity(self)
این متد مسئول محاسبهی ظرفیت حداکثر کارمند برای محل کار بر اساس سطح فعلی آن (
self.level) است. منطق محاسبهی ظرفیت برای انواع مختلف محل کار متفاوت است (مثلاً معدن ممکن است با مدرسه فرق داشته باشد). بنابراین، پیادهسازی واقعی این متد در زیرکلاسهایMine،SchoolوCompanyانجام خواهد شد. در کلاس پایهیWorkPlace، این متد بهصورت خالی باpassتعریف میشود.متد calc_costs(self)
این متد مسئول محاسبهی هزینههای نگهداری روزانه برای این محل کار است. مجدداً منطق محاسبهی هزینه نیز برای انواع مختلف محل کار متفاوت است. مانند
calc_capacity، پیادهسازی واقعی این متد در زیرکلاسها انجام خواهد شد. در کلاس پایهیWorkPlace، این متد بهصورت خالی باpassتعریف میشود.متد get_expertise(self)
این متد صرفاً مقدار ویژگی
self.expertiseرا که نشاندهنده نوع تخصص محل کار است، برمیگرداند.متد calc(self)
این متد وضعیت مالی خالص روزانهی مربوط به خود محل کار را محاسبه میکند. معمولاً محلهای کار درآمدی تولید نمیکنند (این افراد هستند که درآمد تولید میکنند)، بلکه صرفاً هزینه دارند. بنابراین، این متد منفیِ هزینهی نگهداری روزانه را که توسط متد
self.calc_costs()محاسبه میشود، برمیگرداند.متد calc_all()
این متد به عنوان یک متد ایستا (Static Method) تعریف شدهاست و مسئول محاسبهی مجموع وضعیت مالی روزانهی تمام محلهای کاری است که در مدل ما وجود دارند. برای این کار، این متد روی لیست
WorkPlace.instances(که شامل تمام اشیاءWorkPlaceاست) پیمایش میکند و برای هر شیء، متدcalc()آن محل کار را فراخوانی کرده و نتایج را با هم جمع میبندد. در نهایت، مقدار مجموع نهایی را برمیگرداند.
def __init__(self, name):
self.name = name
self.level = 1
self.expertise = ""
self.employees = []
self.capacity = 1
WorkPlace.instances.append(self)
def get_price(self):
return Consts.BASE_PRICE[self.expertise]
def upgrade(self):
self.level += 1
self.calc_capacity()
def hire(self, person):
if len(self.employees) >= self.capacity:
raise WorkPlaceIsFull()
self.employees.append(person)
person.work_place = self
def calc_capacity(self):
pass
def calc_costs(self):
pass
def get_expertise(self):
return self.expertise
def calc(self):
return -self.calc_costs()
@staticmethod
def calc_all():
total = 0
for wp in WorkPlace.instances:
total += wp.calc()
return total
💡 چالشهای حل تمرین
⚠️ چگونه میتوانم به ویژگی
instancesدسترسی داشته باشم؟ویژگی
instancesمربوط به کلاس است (نه به شیء)؛ بنابراین بهصورتWorkPlace.instancesمیتوان به این ویژگی دسترسی داشت.
⚠️ در متد
hire()ازtry...exceptاستفاده کردم ولی تابع بهدرستی کار نمیکند. مشکل چیست؟در تابع
hire()نیازی به استفاده ازtry...exceptنیست. با استفاده ازif...elseمیتوان خواستهی تمرین را برآورده کرد.
⚠️ چگونه در متد
hire()محل کار شخص را برابر این محل کار قرار دهم؟برای این که محل کار شخص را برابر
selfقرار دهید، میتوانید بهصورت زیر عمل کنید:
person.work_place = self
⚠️ مشکلات متداول
- در هیچکدام از توابع نباید مقداری را چاپ کنید، بلکه باید مقادیر خواستهشده را با استفاده از
returnبرگردانید.
✅ این تمرین را در ویرایشگر خود پیادهسازی کنید. به یاد داشته باشید که کلاس
WorkPlaceباید در فایلwork_place.pyقرار گیرد.
نمونهها
w = WorkPlace("Base")
[w.name, w.level, w.expertise, w.employees, w.capacity]
WorkPlace.instances[-1] is w['Base', 1, '', [], 1] True
class Mine(WorkPlace):
def __init__(self, name):
super().__init__(name)
self.expertise = "mine"
m = Mine("M1")
[m.get_price(), m.get_expertise()][150, 'mine']
class P:
work_place = None
w = WorkPlace("W")
x = P()
w.hire(x)
x.work_place is w
try:
w.hire(P())
except WorkPlaceIsFull as error:
print(error)
len(w.employees)True work place is full! 1
class Grow(WorkPlace):
def calc_capacity(self):
self.capacity = self.level * 3
g = Grow("G")
g.upgrade()
[g.level, g.capacity][2, 6]
class Costly(WorkPlace):
def calc_costs(self):
return 100 * self.level
a = Costly("a")
b = Costly("b")
b.upgrade()
[a.calc(), b.calc(), WorkPlace.calc_all()][-100, -200, -300]
[str(WorkPlaceIsFull()), issubclass(WorkPlaceIsFull, Exception)]
['work place is full!', True]
برای نوشتن پاسخ و دریافت امتیاز، ابتدا وارد حساب شوید.
ورود