یاد بگیرید. بسازید.

۸. پروژه نهایی پایتون؛ مدیریت هزینه با ذخیره فایل

آموخته‌ها را در یک برنامه کوچک کنار هم بگذار: اعتبارسنجی خرید، ذخیره JSON، گزارش بودجه و آزمون رفتار.

نکس‌کد؛ پایتون از اولین خط تا پروژه مدیریت هزینه

اول رفتار برنامه را مشخص کن

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

  1. داده قبلی را از فایل بخوان؛ اگر فایل نیست از لیست خالی شروع کن.
  2. عنوان خالی و مبلغ غیرمثبت را نپذیر.
  3. خرید معتبر را به لیست اضافه کن و فایل را ذخیره کن.
  4. جمع را حساب کن و مانده بودجه را نمایش بده.

برنامه کامل؛ از بالا به پایین بخوان

دفتر هزینه من

بودجه و خریدهای پایین فایل را تغییر بده. در اجرای دوم همان فایل، خریدها دوباره اضافه می‌شوند.

main.pypython
import json
from pathlib import Path

def load_expenses(path):
    if not path.exists():
        return []
    return json.loads(path.read_text(encoding="utf-8"))

def add_expense(expenses, title, amount):
    title = title.strip()
    if not title:
        raise ValueError("عنوان خرید خالی است")
    if type(amount) is not int or amount <= 0:
        raise ValueError("مبلغ باید عدد صحیح مثبت باشد")
    expenses.append({"title": title, "amount": amount})

def total_expenses(expenses):
    total = 0
    for expense in expenses:
        total += expense["amount"]
    return total

def save_expenses(path, expenses):
    text = json.dumps(expenses, ensure_ascii=False, indent=2)
    path.write_text(text, encoding="utf-8")

path = Path("my-expenses.json")
budget = 200000

try:
    expenses = load_expenses(path)
    add_expense(expenses, "ناهار", 80000)
    add_expense(expenses, "دفتر", 45000)
    save_expenses(path, expenses)
    total = total_expenses(expenses)
    print(f"تعداد خرید: {len(expenses)}")
    print(f"جمع: {total} تومان")
    remaining = budget - total
    if remaining >= 0:
        print(f"مانده بودجه: {remaining} تومان")
    else:
        print(f"کسری بودجه: {-remaining} تومان")
except json.JSONDecodeError:
    print("فایل JSON خراب است؛ اول یک کپی از آن نگه دار و اصلاحش کن.")
except ValueError as error:
    print(error)
except OSError as error:
    print(f"خواندن یا ذخیره فایل انجام نشد: {error}")
یک راهنمایی می‌خواهم

strip فاصله اول و آخر عنوان را حذف می‌کند.

راهنمایی بیشتر

raise یک خطای مشخص ایجاد می‌کند؛ except پایین فایل پیامش را نشان می‌دهد.

راهنمایی بیشتر

برای شروع دوباره، بازنشانی محیط را بزن؛ فایل موقت هم حذف می‌شود.

در اولین اجرا، دو خرید با جمع ۱۲۵۰۰۰ و مانده ۷۵۰۰۰ می‌بینی. اجرای بعدی دو خرید دیگر به فایل موقت اضافه می‌کند: جمع ۲۵۰۰۰۰ و کسری ۵۰۰۰۰. چون محیط پایتون این مثال بین اجراها حفظ می‌شود، فایل قبلی را دوباره می‌خوانیم. برای شروع از صفر «بازنشانی» را بزن.

چهار تابع هر کدام یک کار دارند. شرط exists نبودن فایل را پوشش می‌دهد. raise خطای ورودی را می‌سازد. as error خود خطا را با یک نام در دسترس می‌گذارد. علامت منفی در -remaining کسری منفی را برای نمایش به عدد مثبت تبدیل می‌کند.

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

چک‌لیست رفتار؛ هر بار محیط را از نو شروع کن
تغییرانتظار
اجرای نمونه بدون تغییر۲ خرید، جمع ۱۲۵۰۰۰، مانده ۷۵۰۰۰
بودجه را ۱۰۰۰۰۰ کنکسری ۲۵۰۰۰
عنوان خرید اول را " " کنپیام عنوان خالی؛ خرید تازه ذخیره نشود
مبلغ خرید اول را -1 کنپیام مبلغ مثبت؛ خرید تازه ذخیره نشود
دو خط add_expense را حذف کنجمع صفر در محیط تازه

دکمه آزمون‌ها چند رفتار تابع جمع را بررسی می‌کند. جدول بالا رفتار کل برنامه و خطاها را هم پوشش می‌دهد. پروژه را بدون نگاه به نمونه بازسازی کن: اول جمع، بعد افزودن خرید، بعد فایل. اگر جایی گیر کردی، همان بخش را کوچک و جدا اجرا کن.

قدم بعدی: یک تغییر کوچک از خودت

چالش: category را به هر خرید اضافه کن و گزارش دسته‌ای درس ششم را روی این پروژه اجرا کن. بعد ورودی‌های پایین فایل را در نسخه محلی با input جایگزین کن؛ مبلغ متن است و باید قبل از ثبت با int تبدیل شود. این تبدیل را هم داخل try بگذار.

برای نصب کتابخانه بیرونی در پروژه‌های بعدی، اول محیط جدا بساز: ویندوز py -m venv .venv و مک/لینوکس python3 -m venv .venv. در ویندوز می‌توانی بدون فعال‌سازی از .venv\Scripts\python -m pip install نام‌بسته و در مک/لینوکس از .venv/bin/python -m pip install نام‌بسته استفاده کنی. پروژه فعلی فقط کتابخانه استاندارد می‌خواهد و نیازی به نصب بسته ندارد.

ادامه مسیر