Skip to content

Commit 7311964

Browse files
Merge pull request steam-bell-92#853 from Prachi0942/feature/Budget-Tracker
Added Budget Tracker CLI tool under utilities
2 parents 4a9a15d + d731b5d commit 7311964

2 files changed

Lines changed: 293 additions & 0 deletions

File tree

utilities/Budget-Tracker/README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# 💰 Budget Tracker CLI
2+
3+
A beginner-friendly command-line tool to track your **income and expenses**, view **balance summaries**, and analyze **category-wise spending** — all saved persistently in a CSV file.
4+
5+
---
6+
7+
## 🚀 Features
8+
9+
- ➕ Add income entries with category and description
10+
- ➖ Add expense entries with category and description
11+
- 📋 View all transactions in a clean formatted table
12+
- 📊 View overall summary (total income, expenses, balance)
13+
- 🗂️ Category-wise breakdown of income and expenses
14+
- 🗑️ Clear all data with confirmation prompt
15+
- 💾 Data persists across sessions via `budget_data.csv`
16+
17+
---
18+
19+
## 🛠️ Requirements
20+
21+
- Python 3.x
22+
- No external libraries needed (uses only built-in modules)
23+
24+
---
25+
26+
## ▶️ How to Run
27+
28+
cd utilities/Budget-Tracker
29+
python budget_tracker.py
30+
31+
---
32+
33+
## 🎮 Menu Options
34+
35+
1. ➕ Add Income
36+
2. ➖ Add Expense
37+
3. 📋 View All Transactions
38+
4. 📊 View Summary
39+
5. 🗂️ Category-wise Breakdown
40+
6. 🗑️ Clear All Data
41+
7. 🚪 Exit
42+
43+
---
44+
45+
## 📸 Sample Output
46+
47+
Adding an Expense:
48+
Category (e.g. Food, Rent, Salary): Food
49+
Description (optional): Lunch
50+
Amount (₹): 150
51+
✅ Expense of ₹150.00 added under 'Food'.
52+
53+
Budget Summary:
54+
Total Income : ₹5000.00
55+
Total Expenses: ₹950.00
56+
✅ Balance : ₹4050.00
57+
58+
---
59+
60+
## 📁 File Structure
61+
62+
Budget-Tracker/
63+
├── budget_tracker.py
64+
├── budget_data.csv
65+
└── README.md
66+
67+
Note: budget_data.csv is auto-generated on first run.
68+
69+
---
70+
71+
## 👤 Author
72+
73+
Contributed as part of GSSoC (GirlScript Summer of Code)
74+
Repository: https://github.com/steam-bell-92/python-mini-project
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
2+
"""
3+
💰 Budget Tracker CLI Tool
4+
A command-line budget tracker to manage income, expenses, and view summaries by category.
5+
Data is saved persistently in a CSV file.
6+
"""
7+
8+
import csv
9+
import os
10+
from datetime import datetime
11+
from collections import defaultdict
12+
13+
DATA_FILE = "budget_data.csv"
14+
FIELDNAMES = ["date", "type", "category", "description", "amount"]
15+
16+
# ─────────────────────────────────────────────
17+
# FILE HELPERS
18+
# ─────────────────────────────────────────────
19+
20+
def initialize_file():
21+
"""Create the CSV file with headers if it doesn't exist."""
22+
if not os.path.exists(DATA_FILE):
23+
with open(DATA_FILE, mode="w", newline="") as f:
24+
writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
25+
writer.writeheader()
26+
27+
28+
def load_transactions():
29+
"""Load all transactions from CSV."""
30+
transactions = []
31+
with open(DATA_FILE, mode="r", newline="") as f:
32+
reader = csv.DictReader(f)
33+
for row in reader:
34+
row["amount"] = float(row["amount"])
35+
transactions.append(row)
36+
return transactions
37+
38+
39+
def save_transaction(entry):
40+
"""Append a single transaction to the CSV."""
41+
with open(DATA_FILE, mode="a", newline="") as f:
42+
writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
43+
writer.writerow(entry)
44+
45+
46+
# ─────────────────────────────────────────────
47+
# CORE FEATURES
48+
# ─────────────────────────────────────────────
49+
50+
def add_transaction(trans_type):
51+
"""Add an income or expense entry."""
52+
print(f"\n── Add {trans_type.capitalize()} ──")
53+
54+
category = input("Category (e.g. Food, Rent, Salary): ").strip()
55+
if not category:
56+
print("❌ Category cannot be empty.")
57+
return
58+
59+
description = input("Description (optional): ").strip()
60+
61+
try:
62+
amount = float(input("Amount (₹): ").strip())
63+
if amount <= 0:
64+
print("❌ Amount must be greater than 0.")
65+
return
66+
except ValueError:
67+
print("❌ Invalid amount. Please enter a number.")
68+
return
69+
70+
entry = {
71+
"date": datetime.now().strftime("%Y-%m-%d %H:%M"),
72+
"type": trans_type,
73+
"category": category.capitalize(),
74+
"description": description,
75+
"amount": round(amount, 2),
76+
}
77+
78+
save_transaction(entry)
79+
print(f"✅ {trans_type.capitalize()} of ₹{amount:.2f} added under '{category.capitalize()}'.")
80+
81+
82+
def view_summary():
83+
"""Show total income, expenses, and current balance."""
84+
transactions = load_transactions()
85+
86+
if not transactions:
87+
print("\n📭 No transactions found.")
88+
return
89+
90+
total_income = sum(t["amount"] for t in transactions if t["type"] == "income")
91+
total_expense = sum(t["amount"] for t in transactions if t["type"] == "expense")
92+
balance = total_income - total_expense
93+
94+
print("\n" + "═" * 35)
95+
print(" 💰 BUDGET SUMMARY")
96+
print("═" * 35)
97+
print(f" Total Income : ₹{total_income:>10.2f}")
98+
print(f" Total Expenses: ₹{total_expense:>10.2f}")
99+
print("─" * 35)
100+
balance_label = "✅ Balance" if balance >= 0 else "⚠️ Deficit"
101+
print(f" {balance_label} : ₹{abs(balance):>10.2f}")
102+
print("═" * 35)
103+
104+
105+
def view_category_summary():
106+
"""Show spending/income broken down by category."""
107+
transactions = load_transactions()
108+
109+
if not transactions:
110+
print("\n📭 No transactions found.")
111+
return
112+
113+
income_by_cat = defaultdict(float)
114+
expense_by_cat = defaultdict(float)
115+
116+
for t in transactions:
117+
if t["type"] == "income":
118+
income_by_cat[t["category"]] += t["amount"]
119+
else:
120+
expense_by_cat[t["category"]] += t["amount"]
121+
122+
print("\n" + "═" * 35)
123+
print(" 📊 CATEGORY-WISE BREAKDOWN")
124+
print("═" * 35)
125+
126+
if income_by_cat:
127+
print("\n 📈 Income:")
128+
for cat, amt in sorted(income_by_cat.items()):
129+
print(f" {cat:<20}{amt:.2f}")
130+
131+
if expense_by_cat:
132+
print("\n 📉 Expenses:")
133+
for cat, amt in sorted(expense_by_cat.items()):
134+
print(f" {cat:<20}{amt:.2f}")
135+
136+
print("═" * 35)
137+
138+
139+
def view_all_transactions():
140+
"""Display all recorded transactions."""
141+
transactions = load_transactions()
142+
143+
if not transactions:
144+
print("\n📭 No transactions found.")
145+
return
146+
147+
print("\n" + "═" * 70)
148+
print(f" {'DATE':<17} {'TYPE':<10} {'CATEGORY':<15} {'DESCRIPTION':<15} {'AMOUNT':>8}")
149+
print("─" * 70)
150+
151+
for t in transactions:
152+
symbol = "+" if t["type"] == "income" else "-"
153+
print(
154+
f" {t['date']:<17} {t['type']:<10} {t['category']:<15} "
155+
f"{t['description'][:14]:<15} {symbol}{t['amount']:>7.2f}"
156+
)
157+
158+
print("═" * 70)
159+
160+
161+
def delete_all_transactions():
162+
"""Clear all transaction data after confirmation."""
163+
confirm = input("\n⚠️ Are you sure you want to delete ALL data? (yes/no): ").strip().lower()
164+
if confirm == "yes":
165+
with open(DATA_FILE, mode="w", newline="") as f:
166+
writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
167+
writer.writeheader()
168+
print("🗑️ All transactions deleted.")
169+
else:
170+
print("❌ Cancelled.")
171+
172+
173+
# ─────────────────────────────────────────────
174+
# MAIN MENU
175+
# ─────────────────────────────────────────────
176+
177+
def print_menu():
178+
print("\n" + "═" * 35)
179+
print(" 💰 BUDGET TRACKER CLI")
180+
print("═" * 35)
181+
print(" 1. ➕ Add Income")
182+
print(" 2. ➖ Add Expense")
183+
print(" 3. 📋 View All Transactions")
184+
print(" 4. 📊 View Summary")
185+
print(" 5. 🗂️ Category-wise Breakdown")
186+
print(" 6. 🗑️ Clear All Data")
187+
print(" 7. 🚪 Exit")
188+
print("═" * 35)
189+
190+
191+
def main():
192+
initialize_file()
193+
print("\n👋 Welcome to Budget Tracker!")
194+
195+
while True:
196+
print_menu()
197+
choice = input(" Enter your choice (1-7): ").strip()
198+
199+
if choice == "1":
200+
add_transaction("income")
201+
elif choice == "2":
202+
add_transaction("expense")
203+
elif choice == "3":
204+
view_all_transactions()
205+
elif choice == "4":
206+
view_summary()
207+
elif choice == "5":
208+
view_category_summary()
209+
elif choice == "6":
210+
delete_all_transactions()
211+
elif choice == "7":
212+
print("\n👋 Goodbye! Keep tracking your budget. 💸\n")
213+
break
214+
else:
215+
print("❌ Invalid choice. Please enter a number between 1 and 7.")
216+
217+
218+
if __name__ == "__main__":
219+
main()

0 commit comments

Comments
 (0)