Skip to content

Commit 2675633

Browse files
committed
Added personal finance tracker project
1 parent c1d34bb commit 2675633

File tree

6 files changed

+317
-0
lines changed

6 files changed

+317
-0
lines changed

personal-finance-tracker/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Personal Finance Tracker
2+
3+
Project Overview:
4+
The Personal Finance Tracker is a simple command-line application that helps users track their income, expenses, and savings goals. It also provides visualizations of spending patterns to better understand financial habits. The project uses SQLite for data storage and Matplotlib for creating various financial charts.
5+
6+
Features:
7+
Add Income: Record income entries with descriptions and amounts.
8+
Add Expense: Record expenses, categorize them, and add descriptions.
9+
View Summary: View a summary of total income, expenses, and balance.
10+
Set Savings Goals: Define and track savings goals.
11+
Visualize Spending: Generate various charts (bar chart, pie chart, line chart, etc.) to better understand your spending habits.
12+
13+
Technologies Used:
14+
Python: Core programming language.
15+
SQLite3: Local database for storing transaction records.
16+
Matplotlib: Python library for generating visualizations.
17+
18+
19+
To run the program:
20+
1] Clone the repository
21+
2] Navigate to Personal Finance Tracker folder
22+
3] Run the main.py file
23+
24+
When you run the application, a menu will appear with the following options:
25+
26+
Add Income: Enter the amount and description of your income.
27+
Add Expense: Enter the amount, category, and description of the expense.
28+
View Summary: See your total income, expenses, and remaining balance.
29+
Set Savings Goal: Set a savings goal to track progress.
30+
Visualize Spending: Choose from various charts to visualize your spending patterns.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import sqlite3
2+
3+
DB_FILE = "data/finance.db"
4+
5+
def get_connection():
6+
conn = sqlite3.connect(DB_FILE)
7+
return conn
8+
9+
def initialize_database():
10+
conn = get_connection()
11+
cursor = conn.cursor()
12+
13+
# Create income and expense table
14+
cursor.execute('''
15+
CREATE TABLE IF NOT EXISTS transactions (
16+
id INTEGER PRIMARY KEY AUTOINCREMENT,
17+
type TEXT NOT NULL,
18+
category TEXT NOT NULL,
19+
amount REAL NOT NULL,
20+
date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
21+
)
22+
''')
23+
24+
# Create table for savings goal
25+
cursor.execute('''
26+
CREATE TABLE IF NOT EXISTS savings_goal (
27+
id INTEGER PRIMARY KEY,
28+
goal_amount REAL NOT NULL
29+
)
30+
''')
31+
32+
conn.commit()
33+
conn.close()

personal-finance-tracker/main.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import tracker
2+
import savings
3+
import visualization
4+
import database
5+
6+
def main_menu():
7+
while True:
8+
print("\n--- Personal Finance Tracker ---")
9+
print("1. Add Income")
10+
print("2. Add Expense")
11+
print("3. View Summary")
12+
print("4. Set Savings Goal")
13+
print("5. Visualize Spending")
14+
print("6. Exit")
15+
16+
choice = input("Choose an option: ")
17+
18+
if choice == "1":
19+
tracker.add_income()
20+
elif choice == "2":
21+
tracker.add_expense()
22+
elif choice == "3":
23+
tracker.view_summary()
24+
elif choice == "4":
25+
savings.set_goal()
26+
elif choice == "5":
27+
visualization.visualize_data()
28+
elif choice == "6":
29+
print("Exiting...")
30+
break
31+
else:
32+
print("Invalid option. Please try again.")
33+
34+
if __name__ == "__main__":
35+
database.initialize_database()
36+
main_menu()
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from database import get_connection
2+
3+
def set_goal():
4+
goal_amount = float(input("Enter your savings goal: "))
5+
6+
conn = get_connection()
7+
cursor = conn.cursor()
8+
9+
cursor.execute("INSERT OR REPLACE INTO savings_goal (id, goal_amount) VALUES (1, ?)", (goal_amount,))
10+
conn.commit()
11+
conn.close()
12+
13+
print(f"Savings goal of {goal_amount} set successfully!")
14+
15+
def track_savings_progress(balance):
16+
conn = get_connection()
17+
cursor = conn.cursor()
18+
19+
cursor.execute("SELECT goal_amount FROM savings_goal WHERE id = 1")
20+
goal_row = cursor.fetchone()
21+
conn.close()
22+
23+
if goal_row:
24+
goal_amount = goal_row[0]
25+
remaining = goal_amount - balance
26+
if remaining > 0:
27+
print(f"You need to save {remaining} more to reach your goal.")
28+
else:
29+
print(f"Congratulations! You've reached your savings goal.")
30+
else:
31+
print("No savings goal set.")
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import sqlite3
2+
from database import get_connection
3+
4+
def add_income():
5+
category = input("Enter income source (e.g., Salary, Freelance): ")
6+
amount = float(input("Enter amount: "))
7+
8+
conn = get_connection()
9+
cursor = conn.cursor()
10+
11+
cursor.execute("INSERT INTO transactions (type, category, amount) VALUES (?, ?, ?)",
12+
("Income", category, amount))
13+
conn.commit()
14+
conn.close()
15+
16+
print("Income added successfully!")
17+
18+
def add_expense():
19+
category = input("Enter expense category (e.g., Rent, Groceries): ")
20+
amount = float(input("Enter amount: "))
21+
22+
conn = get_connection()
23+
cursor = conn.cursor()
24+
25+
cursor.execute("INSERT INTO transactions (type, category, amount) VALUES (?, ?, ?)",
26+
("Expense", category, amount))
27+
conn.commit()
28+
conn.close()
29+
30+
print("Expense added successfully!")
31+
32+
def view_summary():
33+
conn = get_connection()
34+
cursor = conn.cursor()
35+
36+
cursor.execute("SELECT SUM(amount) FROM transactions WHERE type = 'Income'")
37+
total_income = cursor.fetchone()[0] or 0.0
38+
39+
cursor.execute("SELECT SUM(amount) FROM transactions WHERE type = 'Expense'")
40+
total_expenses = cursor.fetchone()[0] or 0.0
41+
42+
balance = total_income - total_expenses
43+
44+
conn.close()
45+
46+
print(f"\nTotal Income: {total_income}")
47+
print(f"Total Expenses: {total_expenses}")
48+
print(f"Balance: {balance}")
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import matplotlib.pyplot as plt
2+
from database import get_connection
3+
4+
def bar_chart_expense():
5+
conn = get_connection()
6+
cursor = conn.cursor()
7+
8+
cursor.execute("SELECT category, SUM(amount) FROM transactions WHERE type = 'Expense' GROUP BY category")
9+
rows = cursor.fetchall()
10+
conn.close()
11+
12+
if rows:
13+
categories = [row[0] for row in rows]
14+
amounts = [row[1] for row in rows]
15+
16+
plt.bar(categories, amounts)
17+
plt.xlabel('Category')
18+
plt.ylabel('Amount')
19+
plt.title('Spending by Category')
20+
plt.xticks(rotation=45)
21+
plt.tight_layout()
22+
plt.show()
23+
else:
24+
print("No expenses recorded yet.")
25+
26+
def pie_chart_expense():
27+
conn = get_connection()
28+
cursor = conn.cursor()
29+
30+
cursor.execute("SELECT category, SUM(amount) FROM transactions WHERE type = 'Expense' GROUP BY category")
31+
rows = cursor.fetchall()
32+
conn.close()
33+
34+
if rows:
35+
categories = [row[0] for row in rows]
36+
amounts = [row[1] for row in rows]
37+
38+
plt.pie(amounts, labels=categories, autopct='%1.1f%%', startangle=90)
39+
plt.title('Spending by Category')
40+
plt.tight_layout()
41+
plt.show()
42+
else:
43+
print("No expenses recorded yet.")
44+
45+
def line_chart_expense_over_time():
46+
conn = get_connection()
47+
cursor = conn.cursor()
48+
49+
cursor.execute("SELECT date, SUM(amount) FROM transactions WHERE type = 'Expense' GROUP BY date")
50+
rows = cursor.fetchall()
51+
conn.close()
52+
53+
if rows:
54+
dates = [row[0] for row in rows]
55+
amounts = [row[1] for row in rows]
56+
57+
plt.plot(dates, amounts, marker='o')
58+
plt.xlabel('Date')
59+
plt.ylabel('Amount')
60+
plt.title('Expenses Over Time')
61+
plt.xticks(rotation=45)
62+
plt.tight_layout()
63+
plt.show()
64+
else:
65+
print("No expenses recorded yet.")
66+
67+
def stacked_bar_chart_income_expense():
68+
conn = get_connection()
69+
cursor = conn.cursor()
70+
71+
cursor.execute("SELECT date, SUM(amount) FROM transactions WHERE type = 'Income' GROUP BY date")
72+
income_rows = cursor.fetchall()
73+
74+
cursor.execute("SELECT date, SUM(amount) FROM transactions WHERE type = 'Expense' GROUP BY date")
75+
expense_rows = cursor.fetchall()
76+
77+
conn.close()
78+
79+
if income_rows and expense_rows:
80+
income_dates = [row[0] for row in income_rows]
81+
income_amounts = [row[1] for row in income_rows]
82+
expense_dates = [row[0] for row in expense_rows]
83+
expense_amounts = [row[1] for row in expense_rows]
84+
85+
plt.bar(income_dates, income_amounts, label='Income')
86+
plt.bar(expense_dates, expense_amounts, bottom=income_amounts, label='Expense')
87+
88+
plt.xlabel('Date')
89+
plt.ylabel('Amount')
90+
plt.title('Income vs Expenses Over Time')
91+
plt.xticks(rotation=45)
92+
plt.legend()
93+
plt.tight_layout()
94+
plt.show()
95+
else:
96+
print("Not enough data to generate this chart.")
97+
98+
def histogram_expense_distribution():
99+
conn = get_connection()
100+
cursor = conn.cursor()
101+
102+
cursor.execute("SELECT amount FROM transactions WHERE type = 'Expense'")
103+
rows = cursor.fetchall()
104+
conn.close()
105+
106+
if rows:
107+
amounts = [row[0] for row in rows]
108+
109+
plt.hist(amounts, bins=10)
110+
plt.xlabel('Expense Amount')
111+
plt.ylabel('Frequency')
112+
plt.title('Expense Distribution')
113+
plt.tight_layout()
114+
plt.show()
115+
else:
116+
print("No expenses recorded yet.")
117+
118+
def visualize_data():
119+
print("\n--- Visualization Menu ---")
120+
print("1. Bar Chart (Spending by Category)")
121+
print("2. Pie Chart (Spending by Category)")
122+
print("3. Line Chart (Expenses Over Time)")
123+
print("4. Stacked Bar Chart (Income vs Expenses)")
124+
print("5. Histogram (Expense Distribution)")
125+
126+
choice = input("Select a visualization option (1-5): ")
127+
128+
if choice == "1":
129+
bar_chart_expense()
130+
elif choice == "2":
131+
pie_chart_expense()
132+
elif choice == "3":
133+
line_chart_expense_over_time()
134+
elif choice == "4":
135+
stacked_bar_chart_income_expense()
136+
elif choice == "5":
137+
histogram_expense_distribution()
138+
else:
139+
print("Invalid choice. Please select a valid option.")

0 commit comments

Comments
 (0)