کلاس Person
کلاس
Constsو کلاسPersonرا در همین یک فایل بنویس. داور برای آزمودنcalcیک زیرکلاس کوچک ازPersonو یک محل کار آزمایشی (فقط باlevel) میسازد؛ نیازی به فایلwork_place.pyنیست.
در این بخش، به سراغ پیادهسازی اولین کلاس بنیادین در مدلسازی کشور کوئرا، یعنی کلاس Person (فرد)، میرویم. این کلاس بهعنوان پایهای برای انواع مختلف افراد در مدل ما عمل میکند و ویژگیها و رفتارهای مشترک آنها را در بر میگیرد.
کد کلاس Person در فایل person.py قرار خواهد گرفت.
ثابتهای پروژه: کلاس Consts
در طول پروژه، از مقادیر ثابتی مانند هزینههای پایه برای زندگی یا استخدام استفاده میکنیم. برای سازماندهی این مقادیر، یک کلاس ساده به نام Consts تعریف میشود که این مقادیر ثابت را در خود نگه میدارد. بخشی از این کلاس که مربوط به قیمتهای پایهی کارکنان است، بهصورت زیر تعریف میشود. در این قسمت از پروژه از این مقادیر استفاده نمیکنیم.
class Consts:
BASE_PRICE = {'worker': 1200, 'teacher': 1500, 'engineer': 2000}
BASE_COST = {'worker': 200, 'teacher': 150, 'engineer': 300}
BASE_INCOME = {'worker': {'mine': 800}, 'teacher': {'mine': 300}, 'engineer': {'mine': 1000}}
MIN_AGE = 15
AGE_MUL = 10
کلاس Person
instances: یک متغیر کلاس است، به این معنی که تنها یک کپی از آن وجود دارد که بین تمام اشیاء (نمونههای) ساخته شده از کلاسPersonبه اشتراک گذاشته میشود. هدف آن نگهداری لیستی از تمام اشیاءPersonاست که تاکنون ایجاد شدهاند.name: نام فرد و از نوع رشته است.age: سن فرد و از نوع عدد صحیح است.level: سطح تجربه یا مهارت فرد است. از نوع عدد صحیح است و با مقدار اولیهی ۱ شروع میشود.job: نوع شغل فرد است، از نوع رشته است و با مقدار اولیهی""(رشتهی خالی) شروع میشود.work_place: شیء محل کار که فرد در آن مشغول است. از نوعWorkPlaceاست؛ اما با مقدار اولیهیNoneشروع میشود.
متد سازنده: init(self, name, age)
- پارامترهای
nameوageبرای مقداردهی اولیه ویژگیهای متناظر شیء استفاده میشوند.- ویژگی
levelبا مقدار پیشفرض1مقداردهی میشود.- ویژگیهای
jobوwork_placeبه ترتیب با""وNoneمقداردهی اولیه میشوند، زیرا فرد در لحظهی ایجاد هنوز شغل یا محل کار مشخصی ندارد.- شیء
selfباید به لیستPerson.instancesاضافه شود تا ردیابی تمام افراد امکانپذیر باشد.متد do_level(self, income)
این متد مسئول اعمال تأثیر سطح فرد (
self.level) و سطح محل کار (self.work_place.level) بر روی درآمد پایهی فرد (income) است. این متد مقدار نهایی درآمد تعدیلشده با سطح را برمیگرداند. فرمول محاسبه به شرح زیر است:income × √(self.level × self.work_place.level)
💡 نکته: پیادهسازی این متد (و متد
calcکه از آن استفاده میکند) فرض میکند که ویژگیself.work_placeهنگام فراخوانی این متد،Noneنیست و به یک شیءWorkPlaceمعتبر اشاره میکند که دارای ویژگیlevelاست. در یک برنامهی واقعی، برای مدیریت افراد بیکار، نیاز به افزودن بررسیif self.work_place is not None:خواهید داشت. اما برای این تمرین، فرض بر این است که این متد تنها برای افراد شاغل فراخوانی میشود یا منطق کل برنامه این وضعیت را قبل از فراخوانی مدیریت میکند.متدهای calc_income() و calc_life_cost()
این دو متد برای محاسبهی درآمد روزانه و هزینهی زندگی فرد در نظر گرفته شدهاند.
در کلاس پایهی
Person، پیادهسازی این متدها با کلمهی کلیدیpassانجام میشود؛ زیرا منطق واقعی محاسبه درآمد و هزینه زندگی به نوع شغل فرد وابسته است (مثلاً یک مهندس با یک معلم متفاوت درآمد دارد). پیادهسازی اصلی این متدها در زیرکلاسهایEngineer،TeacherوWorkerانجام خواهد شد.سیستم داوری این پیادهسازیهای خاص شغل را هنگام تست به کد شما اضافه میکند. شما فقط نیاز دارید که این متدها را در کلاس
Personباpassتعریف کنید.متد calc(self)
این متد وضعیت مالی خالص روزانه فرد را محاسبه میکند. برای این کار، ابتدا درآمد پایهی فرد را با فراخوانی
self.calc_income()و هزینهی زندگی او را با فراخوانیself.calc_life_cost()به دست میآورد. سپس درآمد پایه را با استفاده از متدself.do_level()بر اساس سطح فرد و محل کار تعدیل میکند. در نهایت، هزینهی زندگی را از درآمد تعدیلشده کم کرده و نتیجه (درآمد خالص یا زیان) را برمیگرداند.متد calc_all()
این متد بهعنوان یک متد ایستا (Static Method) تعریف شدهاست. هدف این متد، محاسبهی مجموع وضعیت مالی روزانه تمام افرادی است که در مدل ما وجود دارند. برای این کار، این متد روی لیست
Person.instances(که شامل تمام اشیاءPersonاست) پیمایش میکند و برای هر شیء، متدcalc()آن فرد را فراخوانی کرده و نتایج را با هم جمع میبندد و در نهایت، مقدار مجموع نهایی را برمیگرداند.متد get_job(self)
این متد، رشتهی شغل فعلی فرد (
self.job) را برمیگرداند.متد upgrade(self)
این متد سطح تجربهی فرد (
self.level) را یک واحد افزایش میدهد. این متد هیچ مقداری را برنمیگرداند.
def __init__(self, name, age):
self.name = name
self.age = age
self.level = 1
self.job = ""
self.work_place = None
Person.instances.append(self)
def do_level(self, income):
import math
return income * math.sqrt(self.level * self.work_place.level)
def calc_income(self):
pass
def calc_life_cost(self):
pass
def calc(self):
income = self.calc_income()
cost = self.calc_life_cost()
return self.do_level(income) - cost
@staticmethod
def calc_all():
total = 0
for person in Person.instances:
total += person.calc()
return total
def get_job(self):
return self.job
def upgrade(self):
self.level += 1
💡 چالشهای حل تمرین
⚠️ چگونه میتوانم به ویژگی
instancesدسترسی داشته باشم؟ویژگی
instancesمربوط به کلاس است (نه به شیء)؛ بنابراین از طریقPerson.instancesمیتوان به این ویژگی دسترسی داشت.
⚠️ مشکلات متداول
- در هیچکدام از توابع نباید مقداری را چاپ کنید، بلکه باید مقادیر خواسته شده را با استفاده از
returnبرگردانید.- مطمئن شوید که کتابخانهی
mathرا برای استفاده ازmath.sqrtایمپورت کردهاید.
✅ این تمرین را در ویرایشگر خود پیادهسازی کنید. به یاد داشته باشید که کلاس
Personباید در فایلperson.pyقرار گیرد.
نمونهها
ali = Person("Ali", 20)
[ali.name, ali.age, ali.level, ali.job, ali.work_place]
Person.instances[-1] is ali['Ali', 20, 1, '', None] True
a = Person("A", 30)
b = Person("B", 40)
[p.name for p in Person.instances]['A', 'B']
class Place:
level = 4
sara = Person("Sara", 30)
sara.work_place = Place()
sara.upgrade()
sara.level
sara.do_level(100)2 282.842712474619
class Place:
level = 1
class Coder(Person):
def calc_income(self):
return 1000
def calc_life_cost(self):
return 300
reza = Coder("Reza", 25)
reza.work_place = Place()
reza.calc()700.0
class Place:
def __init__(self, level):
self.level = level
class Coder(Person):
def calc_income(self):
return 400
def calc_life_cost(self):
return 100
one = Coder("One", 20)
one.work_place = Place(1)
two = Coder("Two", 30)
two.work_place = Place(9)
Person.calc_all()1400.0
p = Person("Mina", 22)
p.job = "teacher"
p.get_job()
p.upgrade() is None'teacher' True
برای نوشتن پاسخ و دریافت امتیاز، ابتدا وارد حساب شوید.
ورود