عدد جادویی (Strint)
در این تمرین، شما یک کلاس نوع دادهی جدید ایجاد خواهید کرد که از کلاس داخلی int در پایتون ارثبری میکند. هدف این است که رفتار پیشفرض اعداد صحیح را برای مقایسه، جمع، تفریق و نمایش تغییر دهید و یک نوع دادهی جدید با قوانین خاص بسازید.
کلاس Strint
عملیات مقایسهای
مقایسهی دو شیء Strint تنها بر اساس رقم یکان آنها انجام میشود.
Strintاول کوچکتر ازStrintدوم است، اگر رقم یکانStrintاول کوچکتر از رقم یکانStrintدوم باشد.مثال: Strint(84) < Strint(39) نتیجه میدهد True (زیرا رقم یکان ۸۴ یعنی ۴ کوچکتر از رقم یکان ۳۹ یعنی ۹ است).
Strintاول بزرگتر ازStrintدوم است، اگر رقم یکانStrintاول بزرگتر از رقم یکانStrintدوم باشد.مثال: Strint(39) > Strint(84) نتیجه میدهد True (زیرا رقم یکان ۳۹ یعنی ۹ بزرگتر از رقم یکان ۸۴ یعنی ۴ است).
Strintاول مساویStrintدوم است، اگر رقم یکان آنها مساوی باشد.مثال: Strint(84) == Strint(34) نتیجه میدهد True (زیرا رقم یکان هر دو ۴ است). مثال: Strint(12) == Strint(58) نتیجه میدهد False (زیرا رقم یکان آنها یکسان نیست).
مقایسههای <=, >= و != نیز باید بر اساس همین منطق رقم یکان عمل کنند.
عملیات ریاضی
جمع دو شیء
Strintبا تبدیل آنها به نمایش رشتهای و الحاق (concatenation) نمایش رشتهای شیء دوم به انتهای نمایش رشتهای شیء اول انجام میشود. نتیجهی عمل جمع باید یک شیءStrintجدید باشد.مثال: Strint(84) + Strint(39) نتیجه میدهد Strint(8439). مثال: Strint(39) + Strint(84) نتیجه میدهد Strint(3984).
تفاضل دو شیء
Strintبه این صورت است که نمایش رشتهای شیء دوم از انتهای نمایش رشتهای شیء اول حذف میشود.⚠️ شرط معتبر بودن تفریق: تفریق تنها زمانی معتبر است که نمایش رشتهای شیء اول با نمایش رشتهای شیء دوم به پایان برسد.
- اگر نمایش رشتهای شیء اول با نمایش رشتهای شیء دوم به پایان نرسد، باید یک استثنا از نوع
ValueErrorبا پیام دقیق'The subtraction is not valid!'پرتاب شود.- اگر تفریق معتبر بود، نمایش رشتهای شیء دوم از انتهای نمایش رشتهای شیء اول حذف میشود. رشتهی باقیمانده به عدد صحیح تبدیل شده و نتیجه در قالب یک شیء
Strintجدید بازگردانده میشود.- اگر پس از حذف، رشتهی باقیمانده خالی بود (مانند تفریق Strint(123) - Strint(123) که نتیجهاش رشته خالی میشود)، نتیجه باید Strint(0) در نظر گرفته شود.
مثالهای معتبر: Strint(8439) - Strint(39) → Strint(84) Strint(8439) - Strint(8439) → Strint(0) Strint(8439) - Strint(439) → Strint(8) مثال نامعتبر: Strint(8439) - Strint(43) → ValueError (زیرا 8439 با 43 پایان نمیپذیرد)
طول
طول یک شیء Strint برابر با تعداد ارقام در نمایش رشتهای آن است.
مثال: len(Strint(232425)) نتیجه میدهد 6. len(Strint(0)) نتیجه میدهد 1.
فراخوانی
هنگام فراخوانی یک شیء Strint با استفاده از ()، باید عدد با استفاده از ارقام فارسی نمایش داده شود.
مثال: Strint(232425)() باید خروجی دهد: ۲۳۲۴۲۵ مثال: Strint(10)() باید خروجی دهد: ۱۰
نکته: صفرهای بیارزش
مانند اعداد صحیح معمولی، صفرهای سمت چپ در نمایش عددی بیاهمیت هستند و نباید تأثیری روی اجرای توابع داشته باشند.
مثال: Strint(007) معادل Strint(7) است و هر دو مقدار عددی ۷ را دارند.
💡 چالشهای حل تمرین
⚠️ چرا کلاس
Strintازintارث بردهاست؟این باعث میشود اشیاء
Strintبهطور خودکار دارای یک مقدار عددی صحیح باشند و بتوانند در بسیاری از جاهایی که اعداد صحیح عادی استفاده میشوند، به کار روند (البته با رفتارهای عملیاتی که شما تعریف میکنید).
⚠️ چرا این کلاس، تابع سازنده ندارد؟ آیا باید خودم تابع سازنده را تعریف کنم؟
در این کلاس نیازی به تعریف تابع سازنده نیست. خود شیء، حامل مقدار عددی خود خواهد بود. دلیل این امر، همان ارثبری از کلاس
intاست.
⚠️ نوع مقدار ذخیرهشده در شیء دقیقاً چیست، عدد یا رشته؟
از آنجا که این کلاس از کلاس
intارث میبرد، نوع دادهی ذخیرهشده در آن، عدد صحیح خواهد بود. برای پیادهسازی برخی متدها (مانند جمع و تفریق) نیاز خواهید داشت که مقدار عددیselfوotherرا به نمایش رشتهای تبدیل کنید و سپس عملیات رشتهای مورد نیازStrintرا انجام دهید. در پایان عملیات، اگر نتیجه یک عدد بود، باید آن را دوباره بهintتبدیل کرده و برگردانید.
⚠️ چگونه ارقام انگلیسی را به فارسی تبدیل کنم؟
برای تبدیل ارقام لاتین به فارسی در متد
__str__، میتوانید نمایش رشتهای عدد (که بهصورت پیشفرض با ارقام لاتین است) را پیمایش کرده و هر رقم را با معادل فارسی آن جایگزین کنید. استفاده از یک دیکشنری برای نگاشت ارقام لاتین ('0'تا'9') به ارقام فارسی ('۰' تا '۹') رویکرد مناسبی است.در نظر داشته باشید که نمیتوانید از کتابخانههایی که برای این کار ساخته شدهاند استفاده کنید؛ زیرا این کتابخانهها نیاز به نصب جداگانه خواهند داشت.
💡 راهنمایی نهایی
ساختار کلی کلاس Strint به این شکل است:
class Strint(int):
def _units(self, other):
return abs(int(self)) % 10, abs(int(other)) % 10
def __lt__(self, other):
a, b = self._units(other)
return a < b
def __le__(self, other):
a, b = self._units(other)
return a <= b
def __gt__(self, other):
a, b = self._units(other)
return a > b
def __ge__(self, other):
a, b = self._units(other)
return a >= b
def __eq__(self, other):
a, b = self._units(other)
return a == b
def __ne__(self, other):
a, b = self._units(other)
return a != b
__hash__ = int.__hash__
def __add__(self, other):
return Strint(str(int(self)) + str(int(other)))
def __sub__(self, other):
s, t = str(int(self)), str(int(other))
if not s.endswith(t):
raise ValueError("The subtraction is not valid!")
rest = s[:len(s) - len(t)]
return Strint(int(rest) if rest else 0)
def __len__(self):
return len(str(int(self)))
def __call__(self):
return str(int(self)).translate(str.maketrans("0123456789", "۰۱۲۳۴۵۶۷۸۹"))
__lt__و__eq__← مقایسه بر اساس رقم یکان (با% 10)__add__← الحاق رشتهها و بازگشتStrintجدید__sub__← بررسیendswith()و حذف از انتها__len__← تعداد ارقام باlen(str(self))__call__← تبدیل ارقام لاتین به فارسی با دیکشنری- استفاده از
abs()برای مدیریت اعداد منفی در مقایسه- بررسی
endswith()برای اعتبارسنجی تفریق
✅ این تمرین را در ویرایشگر خود پیادهسازی کنید. به یاد داشته باشید که کلاس
Strintازintارثبری میکند و نیازی به تعریف تابع سازنده ندارد.
نمونهها
[Strint(84) < Strint(39), Strint(39) > Strint(84), Strint(84) == Strint(34), Strint(12) == Strint(58)]
[True, True, True, False]
[Strint(39) > Strint(84), Strint(15) <= Strint(25), Strint(19) >= Strint(91), Strint(10) != Strint(20)]
[True, True, True, False]
[Strint(11) != Strint(22), Strint(90) >= Strint(1), Strint(5) <= Strint(16)]
[True, False, True]
Strint(84) + Strint(39) Strint(39) + Strint(84) type(Strint(1) + Strint(2)).__name__
8439 3984 'Strint'
Strint(8439) - Strint(39) Strint(8439) - Strint(8439) Strint(8439) - Strint(439) type(Strint(8439) - Strint(39)).__name__
84 0 8 'Strint'
try:
Strint(8439) - Strint(43)
except ValueError as error:
print(error)The subtraction is not valid!
[len(Strint(232425)), len(Strint(0)), len(Strint(int("007")))][6, 1, 1]
Strint(232425)() Strint(10)()
'۲۳۲۴۲۵' '۱۰'
برای نوشتن پاسخ و دریافت امتیاز، ابتدا وارد حساب شوید.
ورود