تمرين إعادة البناء
متعقب مصروفات 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()اكتب هنا