0% found this document useful (0 votes)
4 views8 pages

Expense Tracker in Python

Uploaded by

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

Expense Tracker in Python

Uploaded by

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

EXPENSE TRACKER IN PYTHON

The Expense Tracker is a desktop-based application developed in Python to help users record,
manage, and monitor their daily financial transactions efficiently.
This project uses Tkinter for the Graphical User Interface (GUI), SQLite3 for local database
management, and tkcalendar for date selection and entry.

The main objective of this project is to provide a simple and user-friendly system where users
can easily add, view, edit, and delete their expense records. Each expense entry includes details
such as Date, Payee, Description, Amount, and Mode of Payment. All data is stored
permanently in a database file named Expense Tracker. DB, ensuring that information is saved
even after the application is closed.

The interface displays all stored expenses in a Treeview table with scrollbars, allowing users to
view and organize records effectively. Additional features include the ability to convert records
into readable sentences, confirm entries before adding them, and clear or delete data securely
with confirmation prompts.

This project demonstrates practical knowledge of event-driven programming, data validation,


and database integration in Python. It also helps students understand how real-world financial
management tools are designed using open-source technologies.

import datetime
import sqlite3
from tkcalendar import DateEntry

from tkinter import *


import [Link] as mb
import [Link] as ttk

# Connecting to the Database


connector = [Link]("Expense [Link]")
cursor = [Link]()

[Link](
'CREATE TABLE IF NOT EXISTS ExpenseTracker (ID INTEGER PRIMARY KEY
AUTOINCREMENT NOT NULL, Date DATETIME, Payee TEXT, Description TEXT,
Amount FLOAT, ModeOfPayment TEXT)'
)
[Link]()

# Functions
def list_all_expenses():
global connector, table
[Link](*table.get_children())

all_data = [Link]('SELECT * FROM ExpenseTracker')


data = all_data.fetchall()

for values in data:


[Link]('', END, values=values)

def view_expense_details():
global table
global date, payee, desc, amnt, MoP

if not [Link]():
[Link]('No expense selected', 'Please select an
expense from the table to view its details')

current_selected_expense = [Link]([Link]())
values = current_selected_expense['values']

expenditure_date = [Link](int(values[1][:4]),
int(values[1][5:7]), int(values[1][8:]))

date.set_date(expenditure_date) ; [Link](values[2]) ;
[Link](values[3]) ; [Link](values[4]) ; [Link](values[5])

def clear_fields():
global desc, payee, amnt, MoP, date, table

today_date = [Link]().date()

[Link]('') ; [Link]('') ; [Link](0.0) ; [Link]('paytm'),


date.set_date(today_date)
table.selection_remove(*[Link]())

def remove_expense():
if not [Link]():
[Link]('No record selected!', 'Please select a record
to delete!')
return

current_selected_expense = [Link]([Link]())
values_selected = current_selected_expense['values']

surety = [Link]('Are you sure?', f'Are you sure that you want
to delete the record of {values_selected[2]}')

if surety:
[Link]('DELETE FROM ExpenseTracker WHERE ID=%d'
% values_selected[0])
[Link]()
list_all_expenses()
[Link]('Record deleted successfully!', 'The record you
wanted to delete has been deleted successfully')

def remove_all_expenses():
surety = [Link]('Are you sure?', 'Are you sure that you want
to delete all the expense items from the database?', icon='warning')

if surety:
[Link](*table.get_children())

[Link]('DELETE FROM ExpenseTracker')


[Link]()

clear_fields()
list_all_expenses()
[Link]('All Expenses deleted', 'All the expenses were
successfully deleted')
else:
[Link]('Ok then', 'The task was aborted and no expense
was deleted!')

def add_another_expense():
global date, payee, desc, amnt, MoP
global connector

if not [Link]() or not [Link]() or not [Link]() or not


[Link]() or not [Link]():
[Link]('Fields empty!', "Please fill all the missing
fields before pressing the add button!")
else:
[Link](
'INSERT INTO ExpenseTracker (Date, Payee, Description,
Amount, ModeOfPayment) VALUES (?, ?, ?, ?, ?)',
(date.get_date(), [Link](), [Link](), [Link](),
[Link]())
)
[Link]()

clear_fields()
list_all_expenses()
[Link]('Expense added', 'The expense whose details you
just entered has been added to the database')

def edit_expense():
global table

def edit_existing_expense():
global date, amnt, desc, payee, MoP
global connector, table
current_selected_expense = [Link]([Link]())
contents = current_selected_expense['values']

[Link]('UPDATE ExpenseTracker SET Date = ?,


Payee = ?, Description = ?, Amount = ?, ModeOfPayment = ? WHERE ID = ?',
(date.get_date(), [Link](),
[Link](), [Link](), [Link](), contents[0]))
[Link]()

clear_fields()
list_all_expenses()

[Link]('Data edited', 'We have updated the data and


stored in the database as you wanted')
edit_btn.destroy()
return

if not [Link]():
[Link]('No expense selected!', 'You have not selected
any expense in the table for us to edit; please do that!')
return

view_expense_details()

edit_btn = Button(data_entry_frame, text='Edit expense',


font=btn_font, width=30,
bg=hlb_btn_bg, command=edit_existing_expense)
edit_btn.place(x=10, y=395)

def selected_expense_to_words():
global table

if not [Link]():
[Link]('No expense selected!', 'Please select an
expense from the table for us to read')
return

current_selected_expense = [Link]([Link]())
values = current_selected_expense['values']

message = f'Your expense can be read like: \n"You paid {values[4]}


to {values[2]} for {values[3]} on {values[1]} via {values[5]}"'

[Link]('Here\'s how to read your expense', message)

def expense_to_words_before_adding():
global date, desc, amnt, payee, MoP

if not date or not desc or not amnt or not payee or not MoP:
[Link]('Incomplete data', 'The data is incomplete,
meaning fill all the fields first!')
message = f'Your expense can be read like: \n"You paid {[Link]()}
to {[Link]()} for {[Link]()} on {date.get_date()} via {[Link]()}"'

add_question = [Link]('Read your record like: ',


f'{message}\n\nShould I add it to the database?')

if add_question:
add_another_expense()
else:
[Link]('Ok', 'Please take your time to add this
record')

# Backgrounds anf Fonts


dataentery_frame_bg = 'pink'
buttons_frame_bg = 'black'
hlb_btn_bg = 'IndianRed'

lbl_font = ('Georgia', 13)


entry_font = 'Times 13 bold'
btn_font = ('Arial black', 13)

# Initializing the GUI window


root = Tk()
[Link]('Expense Tracker')
[Link]('1200x550')
[Link](0, 0)

Label(root, text='EXPENSE TRACK', font=('Noto Sans CJK TC', 15, 'bold'),


bg=hlb_btn_bg).pack(side=TOP, fill=X)

# StringVar and DoubleVar variables


desc = StringVar()
amnt = DoubleVar()
payee = StringVar()
MoP = StringVar(value='paytm')

# Frames
data_entry_frame = Frame(root, bg=dataentery_frame_bg)
data_entry_frame.place(x=0, y=30, relheight=0.95, relwidth=0.25)

buttons_frame = Frame(root, bg=buttons_frame_bg)


buttons_frame.place(relx=0.25, rely=0.05, relwidth=0.75, relheight=0.21)

tree_frame = Frame(root)
tree_frame.place(relx=0.25, rely=0.26, relwidth=0.75, relheight=0.74)

# Data Entry Frame


Label(data_entry_frame, text='Date (M/DD/YY) :', font=lbl_font,
bg=dataentery_frame_bg).place(x=10, y=50)
date = DateEntry(data_entry_frame, date=[Link]().date(),
font=entry_font)
[Link](x=160, y=50)
Label(data_entry_frame, text='Payee\t :', font=lbl_font,
bg=dataentery_frame_bg).place(x=10, y=230)
Entry(data_entry_frame, font=entry_font, width=31, text=payee).place(x=10,
y=260)

Label(data_entry_frame, text='Description :', font=lbl_font,


bg=dataentery_frame_bg).place(x=10, y=100)
Entry(data_entry_frame, font=entry_font, width=31, text=desc).place(x=10,
y=130)

Label(data_entry_frame, text='Amount\t :', font=lbl_font,


bg=dataentery_frame_bg).place(x=10, y=180)
Entry(data_entry_frame, font=entry_font, width=14, text=amnt).place(x=160,
y=180)

Label(data_entry_frame, text='Mode of Payment:', font=lbl_font,


bg=dataentery_frame_bg).place(x=10, y=310)
dd1 = OptionMenu(data_entry_frame, MoP, *['Cash', 'Cheque', 'Credit Card',
'Debit Card', 'Paytm', 'Google Pay', 'Razorpay'])
[Link](x=160, y=305) ; [Link](width=10, font=entry_font)

Button(data_entry_frame, text='Add expense', command=add_another_expense,


font=btn_font, width=30,
bg=hlb_btn_bg).place(x=10, y=395)
Button(data_entry_frame, text='Convert to words before adding',
font=btn_font, width=30, bg=hlb_btn_bg).place(x=10,y=450)

# Buttons' Frame
Button(buttons_frame, text='Delete Expense', font=btn_font, width=25,
bg=hlb_btn_bg, command=remove_expense).place(x=30, y=5)

Button(buttons_frame, text='Clear Fields in DataEntry Frame',


font=btn_font, width=25, bg=hlb_btn_bg,
command=clear_fields).place(x=335, y=5)

Button(buttons_frame, text='Delete All Expenses', font=btn_font, width=25,


bg=hlb_btn_bg, command=remove_all_expenses).place(x=640, y=5)

Button(buttons_frame, text='View Selected Expense\'s Details',


font=btn_font, width=25, bg=hlb_btn_bg,
command=view_expense_details).place(x=30, y=65)

Button(buttons_frame, text='Edit Selected Expense', command=edit_expense,


font=btn_font, width=25, bg=hlb_btn_bg).place(x=335,y=65)

Button(buttons_frame, text='Convert Expense to a sentence', font=btn_font,


width=25, bg=hlb_btn_bg,
command=selected_expense_to_words).place(x=640, y=65)

# Treeview Frame
table = [Link](tree_frame, selectmode=BROWSE, columns=('ID', 'Date',
'Payee', 'Description', 'Amount', 'Mode of Payment'))
X_Scroller = Scrollbar(table, orient=HORIZONTAL, command=[Link])
Y_Scroller = Scrollbar(table, orient=VERTICAL, command=[Link])
X_Scroller.pack(side=BOTTOM, fill=X)
Y_Scroller.pack(side=RIGHT, fill=Y)

[Link](yscrollcommand=Y_Scroller.set, xscrollcommand=X_Scroller.set)

[Link]('ID', text='S No.', anchor=CENTER)


[Link]('Date', text='Date', anchor=CENTER)
[Link]('Payee', text='Payee', anchor=CENTER)
[Link]('Description', text='Description', anchor=CENTER)
[Link]('Amount', text='Amount', anchor=CENTER)
[Link]('Mode of Payment', text='Mode of Payment', anchor=CENTER)

[Link]('#0', width=0, stretch=NO)


[Link]('#1', width=50, stretch=NO)
[Link]('#2', width=95, stretch=NO) # Date column
[Link]('#3', width=150, stretch=NO) # Payee column
[Link]('#4', width=325, stretch=NO) # Title column
[Link]('#5', width=135, stretch=NO) # Amount column
[Link]('#6', width=125, stretch=NO) # Mode of Payment column

[Link](relx=0, y=0, relheight=1, relwidth=1)

list_all_expenses()

# Finalizing the GUI window


[Link]()
[Link]()
OUTPUT :

You might also like