0% found this document useful (0 votes)
3 views7 pages

Project Cs

The document describes a Smart Daily Expense Tracker application built using Tkinter for the GUI and MySQL for database connectivity. It allows users to add, view, and delete expenses, generate reports, and visualize data with Matplotlib graphs. The application automatically creates a database and a table for storing expenses and generates text reports in a specified directory.

Uploaded by

hanuman200800
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views7 pages

Project Cs

The document describes a Smart Daily Expense Tracker application built using Tkinter for the GUI and MySQL for database connectivity. It allows users to add, view, and delete expenses, generate reports, and visualize data with Matplotlib graphs. The application automatically creates a database and a table for storing expenses and generates text reports in a specified directory.

Uploaded by

hanuman200800
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

is pip ko install kr:

pip install
mysql-connector-python
matplotlib

"""
Smart Daily Expense Tracker
Single-file example with:
- Tkinter GUI
- MySQL connectivity (creates DB & table if not exists)
- File handling (generates text report in ./reports/)
- Matplotlib graphs embedded in Tkinter
Author: Example for Class 12 project
"""

import os
import [Link]
from [Link] import errorcode
import tkinter as tk
from tkinter import ttk, messagebox
from tkinter import simpledialog
from datetime import datetime, date
import matplotlib
[Link]("TkAgg")
from [Link] import Figure
from [Link].backend_tkagg import FigureCanvasTkAgg

# ---------------------------
# ====== CONFIGURE DB =======
# ---------------------------
DB_CONFIG = {
"host": "localhost",
"user": "root",
"password": "", # <- set your MySQL root password here
"database": "expense_tracker_db"
}

# ---------------------------
# ====== DB & TABLE SETUP ===
# ---------------------------
def get_db_connection(create_db_if_missing=True):
"""Establish connection. If DB doesn't exist, optionally create it."""
try:
conn = [Link](
host=DB_CONFIG["host"],
user=DB_CONFIG["user"],
password=DB_CONFIG["password"],
)
cursor = [Link]()
# create database if not exists
if create_db_if_missing:
[Link](f"CREATE DATABASE IF NOT EXISTS
{DB_CONFIG['database']}")
[Link] = DB_CONFIG['database']
return conn
except [Link] as err:
[Link]("DB Error", f"Database connection failed:\n{err}")
raise

def setup_table():
conn = get_db_connection()
cursor = [Link]()
create_table = (
"CREATE TABLE IF NOT EXISTS expenses ("
" id INT AUTO_INCREMENT PRIMARY KEY,"
" date DATE NOT NULL,"
" category VARCHAR(50) NOT NULL,"
" amount DECIMAL(10,2) NOT NULL,"
" note VARCHAR(255)"
");"
)
[Link](create_table)
[Link]()
[Link]()
[Link]()

# Ensure reports folder exists


[Link]("reports", exist_ok=True)
setup_table()

# ---------------------------
# ====== DB FUNCTIONS =======
# ---------------------------
def add_expense_to_db(tx_date, category, amount, note):
conn = get_db_connection()
cursor = [Link]()
insert_q = "INSERT INTO expenses (date, category, amount, note) VALUES (%s, %s,
%s, %s)"
[Link](insert_q, (tx_date, category, amount, note))
[Link]()
[Link]()
[Link]()

def fetch_expenses(from_date=None, to_date=None, category=None):


conn = get_db_connection()
cursor = [Link](dictionary=True)
q = "SELECT * FROM expenses WHERE 1=1"
params = []
if from_date:
q += " AND date >= %s"
[Link](from_date)
if to_date:
q += " AND date <= %s"
[Link](to_date)
if category:
q += " AND category = %s"
[Link](category)
q += " ORDER BY date DESC, id DESC"
[Link](q, params)
rows = [Link]()
[Link]()
[Link]()
return rows

def delete_expense(expense_id):
conn = get_db_connection()
cursor = [Link]()
[Link]("DELETE FROM expenses WHERE id = %s", (expense_id,))
[Link]()
[Link]()
[Link]()

def category_summary(from_date=None, to_date=None):


conn = get_db_connection()
cursor = [Link]()
q = "SELECT category, SUM(amount) as total FROM expenses WHERE 1=1"
params = []
if from_date:
q += " AND date >= %s"
[Link](from_date)
if to_date:
q += " AND date <= %s"
[Link](to_date)
q += " GROUP BY category"
[Link](q, params)
rows = [Link]()
[Link]()
[Link]()
return rows # list of tuples (category, total)

# ---------------------------
# ====== GUI FUNCTIONS ======
# ---------------------------
class ExpenseTrackerApp:
def __init__(self, root):
[Link] = root
[Link]("Smart Daily Expense Tracker")
[Link]("780x520")

# Top frame - Add expense


top = [Link](root, text="Add Expense")
[Link](fill="x", padx=10, pady=8)

[Link](top, text="Date (YYYY-MM-DD):").grid(row=0, column=0, padx=6,


pady=6, sticky="w")
self.date_var = [Link](value=str([Link]()))
[Link](top, textvariable=self.date_var, width=14).grid(row=0, column=1,
pady=6)

[Link](top, text="Category:").grid(row=0, column=2, padx=6, pady=6,


sticky="w")
self.category_var = [Link]()
self.category_combo = [Link](top, textvariable=self.category_var,
width=18)
self.category_combo['values'] = ("Food", "Transport", "Shopping",
"Recharge", "Bills", "Misc")
self.category_combo.grid(row=0, column=3, pady=6)
self.category_combo.set("Food")

[Link](top, text="Amount (₹):").grid(row=0, column=4, padx=6, pady=6,


sticky="w")
self.amount_var = [Link]()
[Link](top, textvariable=self.amount_var, width=12).grid(row=0,
column=5, pady=6)

[Link](top, text="Note:").grid(row=1, column=0, padx=6, pady=6,


sticky="w")
self.note_var = [Link]()
[Link](top, textvariable=self.note_var, width=65).grid(row=1, column=1,
columnspan=5, sticky="w", pady=6)

[Link](top, text="Add Expense", command=self.add_expense).grid(row=0,


column=6, padx=8)
[Link](top, text="Show Expenses",
command=self.show_expenses_window).grid(row=0, column=7, padx=8)
[Link](top, text="Show Graphs",
command=self.show_graphs_dialog).grid(row=1, column=6, padx=8)
[Link](top, text="Generate Report",
command=self.generate_report_dialog).grid(row=1, column=7, padx=8)

# Bottom frame - quick info


bottom = [Link](root, text="Quick Summary (Today)")
[Link](fill="both", expand=True, padx=10, pady=8)

self.summary_text = [Link](bottom, height=12)


self.summary_text.pack(fill="both", expand=True, padx=6, pady=6)
self.refresh_today_summary()

def add_expense(self):
dt = self.date_var.get().strip()
cat = self.category_var.get().strip()
amt = self.amount_var.get().strip()
note = self.note_var.get().strip()
if not dt or not cat or not amt:
[Link]("Missing data", "Please fill Date, Category and
Amount.")
return
try:
# validate date and amount
dt_obj = [Link](dt, "%Y-%m-%d").date()
amt_f = float(amt)
except Exception as e:
[Link]("Invalid input", f"Date or amount invalid:\n{e}")
return
add_expense_to_db(dt_obj, cat, amt_f, note)
[Link]("Success", "Expense added.")
# clear amount and note
self.amount_var.set("")
self.note_var.set("")
self.refresh_today_summary()

def refresh_today_summary(self):
today = [Link]()
rows = fetch_expenses(from_date=str(today), to_date=str(today))
total = sum([float(r['amount']) for r in rows])
self.summary_text.delete("1.0", [Link])
self.summary_text.insert([Link], f"Date: {today}\nTotal expenses today: ₹
{total:.2f}\n\nDetails:\n")
if not rows:
self.summary_text.insert([Link], "No expenses today.\n")
else:
for r in rows:
self.summary_text.insert([Link], f"- [{r['id']}] {r['category']}: ₹
{r['amount']} ({r['note']})\n")

def show_expenses_window(self):
win = [Link]([Link])
[Link]("All Expenses")
[Link]("700x420")

# Filter frame
fframe = [Link](win)
[Link](fill="x", padx=6, pady=6)
[Link](fframe, text="From (YYYY-MM-DD)").grid(row=0, column=0, padx=4)
from_var = [Link]()
[Link](fframe, textvariable=from_var, width=12).grid(row=0, column=1,
padx=4)
[Link](fframe, text="To (YYYY-MM-DD)").grid(row=0, column=2, padx=4)
to_var = [Link]()
[Link](fframe, textvariable=to_var, width=12).grid(row=0, column=3,
padx=4)
[Link](fframe, text="Category").grid(row=0, column=4, padx=4)
cat_var = [Link]()
[Link](fframe, textvariable=cat_var, width=15).grid(row=0, column=5,
padx=4)
def apply_filter():
rows = fetch_expenses(from_date=from_var.get() or None,
to_date=to_var.get() or None, category=cat_var.get() or None)
fill_tree(rows)
[Link](fframe, text="Apply Filter", command=apply_filter).grid(row=0,
column=6, padx=4)

# Treeview for results


cols = ("id", "date", "category", "amount", "note")
tree = [Link](win, columns=cols, show="headings", height=15)
for c in cols:
[Link](c, text=[Link]())
[Link](c, width=100)
[Link](fill="both", expand=True, padx=6, pady=6)

# populate initial
def fill_tree(rows):
for i in tree.get_children():
[Link](i)
for r in rows:
[Link]("", [Link], values=(r['id'], r['date'], r['category'],
float(r['amount']), r['note'] or ""))

rows = fetch_expenses()
fill_tree(rows)

# delete button
def delete_selected():
sel = [Link]()
if not sel:
[Link]("Select", "Select a row to delete.")
return
item = [Link](sel[0])
expense_id = item['values'][0]
if [Link]("Confirm", f"Delete expense id {expense_id}?"):
delete_expense(expense_id)
[Link](sel[0])
self.refresh_today_summary()
[Link](win, text="Delete Selected",
command=delete_selected).pack(pady=4)

def show_graphs_dialog(self):
# get month / date range from user
win = [Link]([Link])
[Link]("Graphs - choose range")
[Link]("420x140")
[Link](win, text="From (YYYY-MM-DD):").grid(row=0, column=0, padx=6,
pady=6)
fvar = [Link]()
[Link](win, textvariable=fvar).grid(row=0, column=1)
[Link](win, text="To (YYYY-MM-DD):").grid(row=1, column=0, padx=6,
pady=6)
tvar = [Link]()
[Link](win, textvariable=tvar).grid(row=1, column=1)
def open_graphs():
fd = [Link]() or None
td = [Link]() or None
[Link]()
self.show_graphs_window(fd, td)
[Link](win, text="Show", command=open_graphs).grid(row=2, column=0,
columnspan=2, pady=8)

def show_graphs_window(self, from_date=None, to_date=None):


rows = category_summary(from_date, to_date)
if not rows:
[Link]("No data", "No expenses found for chosen range.")
return
cats = [r[0] for r in rows]
vals = [float(r[1]) for r in rows]

gwin = [Link]([Link])
[Link]("Expense Graphs")
[Link]("900x420")

# Pie chart frame


f1 = [Link](gwin, text="Category-wise (Pie)")
[Link](side="left", fill="both", expand=True, padx=6, pady=6)
fig1 = Figure(figsize=(4,4))
ax1 = fig1.add_subplot(111)
[Link](vals, labels=cats, autopct='%1.1f%%')
canvas1 = FigureCanvasTkAgg(fig1, master=f1)
canvas1.get_tk_widget().pack(fill="both", expand=True)

# Bar chart frame


f2 = [Link](gwin, text="Category Totals (Bar)")
[Link](side="right", fill="both", expand=True, padx=6, pady=6)
fig2 = Figure(figsize=(4,4))
ax2 = fig2.add_subplot(111)
[Link](cats, vals)
ax2.set_ylabel("Amount (₹)")
ax2.set_xticklabels(cats, rotation=30, ha='right')
canvas2 = FigureCanvasTkAgg(fig2, master=f2)
canvas2.get_tk_widget().pack(fill="both", expand=True)
def generate_report_dialog(self):
# ask user for date range
win = [Link]([Link])
[Link]("Generate Report")
[Link](win, text="From (YYYY-MM-DD):").grid(row=0, column=0, padx=6,
pady=6)
fvar = [Link]()
[Link](win, textvariable=fvar).grid(row=0, column=1)
[Link](win, text="To (YYYY-MM-DD):").grid(row=1, column=0, padx=6,
pady=6)
tvar = [Link]()
[Link](win, textvariable=tvar).grid(row=1, column=1)
def gen():
fd = [Link]() or None
td = [Link]() or None
[Link]()
self.generate_report(fd, td)
[Link](win, text="Generate", command=gen).grid(row=2, column=0,
columnspan=2, pady=8)

def generate_report(self, from_date=None, to_date=None):


rows = fetch_expenses(from_date=from_date, to_date=to_date)
if not rows:
[Link]("No data", "No expenses found for chosen range.")
return
total = sum([float(r['amount']) for r in rows])
# category totals
cat_totals = {}
for r in rows:
cat_totals[r['category']] = cat_totals.get(r['category'], 0) +
float(r['amount'])

# create filename with timestamp


ts = [Link]().strftime("%Y%m%d_%H%M%S")
fn = f"reports/report_{ts}.txt"
with open(fn, "w", encoding="utf-8") as f:
[Link]("Smart Daily Expense Tracker - Report\n")
[Link](f"Generated: {[Link]()}\n")
[Link](f"Range: {from_date or 'ALL'} to {to_date or 'ALL'}\n")
[Link]("="*40 + "\n")
[Link](f"Total Expenses: ₹{total:.2f}\n\n")
[Link]("Category wise totals:\n")
for c, v in cat_totals.items():
[Link](f"- {c}: ₹{v:.2f}\n")
[Link]("\nDetailed entries:\n")
for r in rows:
[Link](f"{r['date']} | {r['category']} | ₹{r['amount']} |
{r['note'] or ''}\n")
[Link]("Report Generated", f"Report saved to {fn}")

# ---------------------------
# ====== RUN APP ============
# ---------------------------
if __name__ == "__main__":
root = [Link]()
app = ExpenseTrackerApp(root)
[Link]()

You might also like