AzLearn

تمرين إعادة البناء

متعقب مصروفات CSV

أضف مصروفاً أو اعرض ملخص مصروفات محفوظة في ملف CSV محلي.

python ~25 دقيقة متوسط
أعد بناء الكود Rebuild

هذا هو الكود. اكتبه بنفسك.

الكود المرجعي
import argparse
import csv
from collections import defaultdict
from datetime import date
from pathlib import Path


FIELDS = ["date", "category", "amount_cents", "note"]


def add_expense(path: Path, category: str, amount_cents: int, note: str) -> None:
    exists = path.exists()
    with path.open("a", newline="", encoding="utf-8") as file:
        writer = csv.DictWriter(file, fieldnames=FIELDS)
        if not exists:
            writer.writeheader()
        writer.writerow({
            "date": date.today().isoformat(),
            "category": category,
            "amount_cents": amount_cents,
            "note": note,
        })


def summarize(path: Path) -> None:
    totals: defaultdict[str, int] = defaultdict(int)
    with path.open(newline="", encoding="utf-8") as file:
        for row in csv.DictReader(file):
            totals[row["category"]] += int(row["amount_cents"])
    for category, cents in sorted(totals.items()):
        print(f"{category}: {cents / 100:.2f}")


def main() -> None:
    parser = argparse.ArgumentParser(description="Track expenses in a local CSV file.")
    parser.add_argument("file", type=Path)
    subparsers = parser.add_subparsers(dest="command", required=True)
    add = subparsers.add_parser("add")
    add.add_argument("category")
    add.add_argument("amount_cents", type=int)
    add.add_argument("--note", default="")
    subparsers.add_parser("summary")
    args = parser.parse_args()

    if args.command == "add":
        add_expense(args.file, args.category, args.amount_cents, args.note)
        print("Added")
    else:
        summarize(args.file)


if __name__ == "__main__":
    main()
اكتب هنا