گزارش کوچک هم تعریف دقیق می‌خواهد

برای پاسخ به اینکه «هنوز در بودجه هستیم؟» باید واحد پول، بازهٔ زمانی و معنای هزینه مشخص باشد. در این پروژه یک بودجه و فهرستی از هزینه‌های صحیح غیرمنفی در یک واحد ثابت داریم. بازپرداخت، بدهی قبلی و چند ارز وارد محاسبه نمی‌شوند. هدف، تمرین ساخت گزارشی است که هم عدد درست و هم وضعیت قابل‌توضیح دارد؛ این نمونه مشاورهٔ مالی یا سامانهٔ حسابداری کامل نیست.

سه خروجی به هم وابسته‌اند

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

مرز مساوی را فراموش نکنید

اگر مصرف دقیقاً برابر بودجه باشد، باقیمانده صفر و وضعیت within_budget درست است. استفاده از علامت کوچک‌تر به‌جای کوچک‌تر یا مساوی همین حالت را اشتباه رد می‌کند. تست صفر نیز مهم است: بودجهٔ صفر با هزینهٔ خالی هنوز در بودجه است. این دو نمونه ساده نشان می‌دهند که تشخیص مرز از افزودن ده‌ها مقدار میانی معمولاً مفیدتر است.

باقیماندهٔ منفی اطلاعات است

اگر مصرف بیشتر از بودجه شود، remaining باید منفی بماند. محدودکردن آن به صفر اندازهٔ عبور از سقف را پنهان می‌کند. در رابط کاربری می‌توانید مقدار منفی را با توضیح «بیش‌مصرفی» نمایش دهید، اما دادهٔ محاسباتی را عوض نکنید. تفاوت میان مدل داده و نمایش کمک می‌کند گزارش‌های بعدی، مثل جمع اضافه‌مصرف چند دوره، هنوز از عدد واقعی استفاده کنند.

ناوردای ساده برای کشف خطا

در تمام ورودی‌های معتبر، جمع مصرف و باقیمانده باید برابر بودجه باشد. اگر هزینه‌ای صفر اضافه کنید، نتیجه نباید تغییر کند؛ اگر ترتیب هزینه‌ها عوض شود، جمع ثابت می‌ماند. این رابطه‌ها ناوردا هستند و می‌توانند خطاهایی را پیدا کنند که یک مثال ثابت نمی‌بیند. البته ناوردا به‌تنهایی کافی نیست؛ کدی که همیشه مصرف صفر برمی‌گرداند شاید یک رابطه را حفظ کند اما جواب مسئله نباشد.

دادهٔ خالی با دادهٔ گمشده فرق دارد

فهرست خالی در این قرارداد یعنی هزینه‌ای ثبت نشده و مجموع صفر است. نبودن کلید spent یا فرستادن null معنای دیگری دارد و خارج از ورودی معتبر تمرین است. در API واقعی باید مشخص کنید کدام وضعیت مجاز است و چگونه خطا گزارش می‌شود. تبدیل همهٔ مقدارهای نامعلوم به صفر ممکن است گزارش ناقص را به‌اشتباه سالم نشان دهد و اعتماد کاربر را کاهش دهد.

تمرین توسعه و محدودیت کاربرد

نسخهٔ بعدی می‌تواند هشدار هشتاد درصد بودجه داشته باشد. برای بودجهٔ صفر، محاسبهٔ درصد نیازمند تعریف جداست و نباید تقسیم بر صفر انجام شود. همچنین می‌توانید گزارش چند دوره بسازید، به شرط آنکه دورهٔ هر پرداخت روشن باشد. ابتدا تست‌های مرزی را نگه دارید و سپس قابلیت تازه را اضافه کنید؛ توسعهٔ گزارش نباید رفتار قراردادی قبلی را بی‌دلیل تغییر دهد.

نمونه‌کد و قرارداد پروژه

budget: عدد صحیح غیرمنفی در یک واحد ثابت؛ spent: فهرست هزینه‌های صحیح غیرمنفی. خالی بودن هزینه‌ها مجاز است.

spent: جمع هزینه‌ها؛ remaining: بودجه منهای مصرف و ممکن است منفی شود؛ within_budget: مصرف کمتر یا مساوی بودجه.

def solve(data):
    spent = sum(data['spent'])
    return {'spent': spent, 'remaining': data['budget'] - spent,
            'within_budget': spent <= data['budget']}

print(solve({'budget': 500, 'spent': [120, 80, 90]}))

خروجی مورد انتظار

{
  "spent": 290,
  "remaining": 210,
  "within_budget": true
}

پرسش‌های متداول

چرا باقیمانده به صفر محدود نمی‌شود؟

چون مقدار منفی اندازهٔ عبور از بودجه را نشان می‌دهد؛ تبدیل آن به صفر اطلاعات لازم گزارش را حذف می‌کند.

آیا هزینهٔ منفی مجاز است؟

نه در این تمرین. اگر بازپرداخت لازم باشد، باید قرارداد علامت و اثر آن بر مصرف و دورهٔ مالی صریحاً توسعه یابد.

تمرین عملی و قدم بعدی

پروژهٔ «کنترل بودجهٔ ماهانه» همین قرارداد را در میزکار ارزیابی می‌کند. ابتدا خروجی نمونه را دستی محاسبه کنید، سپس تابع را اجرا کنید و یک ورودی مرزی متفاوت بسازید. نمونه‌کد راهی برای توضیح منطق است؛ برای یادگیری، علت هر شرط و انتخاب ساختار داده را بدون نگاه‌کردن به کد توضیح دهید. اجرای موفق با قبولی ارزیابی متفاوت است؛ نتیجه باید برای تمام حالت‌های تعریف‌شده درست بماند.

منابع و مطالعهٔ بیشتر

برای بررسی جزئیات و ادامهٔ مطالعه؛ متن این راهنما مستقلاً برای نوونتیکس نوشته شده است.