How to build an expense tracker in Python
Tikinter, CSV, Matplotlib modules
To build an expense tracker, you need the Tkinter, CSV, and Matplotlib modules. Tkinter allows you to create desktop applications. It provides a series of widgets like buttons, stickers, and text boxes that make application development easy.
The CSV module is a built-in Python library that provides the ability to read and write CSV files.
With Matplotlib, you can build interactive visualizations such as graphs, diagrams, and charts. Using it with modules like OpenCV can help you master image enhancement techniques.
To install these modules, run:
pip install tk matplotlib
Determine the structure of your expense tracking application
Start by importing the necessary modules. Define a class, ExpenseTrackerApp . Set title and size. Define one list to save expenses and another list to the folder. Initialize a StringVar of category name and set its initial value to the first category in the list. Finish by calling the create_widgets method .
import tkinter as tk from tkinter import ttk, messagebox, simpledialog import csv import matplotlib.pyplot as plt class ExpenseTrackerApp(tk.Tk): def __init__(self): super().__init__() self.title("Expense Tracker") self.geometry("1300x600") self.expenses = [] self.categories = [ "Food", "Transportation", "Utilities", "Entertainment", "Other", ] self.category_var = tk.StringVar(self) self.category_var.set(self.categories[0]) self.create_widgets()
The create_widgets method is responsible for adding UI elements to the application. Create a frame for the expense record labels and items. Create 6 labels: one for title, cost amount, item description, category, date, and total cost. Set each element's parent, the content to display, and its font style.
Create 3 entry widgets and a Combobox to get the corresponding input. For input widget, set parent element, font style and width. Specify the parent element, value list, font style and width for the Combobox. Bind category_var to it, so the selected value is automatically updated.
def create_widgets(self): self.label = tk.Label( self, text="Expense Tracker", font=("Helvetica", 20, "bold") ) self.label.pack(pady=10) self.frame_input = tk.Frame(self) self.frame_input.pack(pady=10) self.expense_label = tk.Label( self.frame_input, text="Expense Amount:", font=("Helvetica", 12) ) self.expense_label.grid(row=0, column=0, padx=5) self.expense_entry = tk.Entry( self.frame_input, font=("Helvetica", 12), width=15 ) self.expense_entry.grid(row=0, column=1, padx=5) self.item_label = tk.Label( self.frame_input, text="Item Description:", font=("Helvetica", 12) ) self.item_label.grid(row=0, column=2, padx=5) self.item_entry = tk.Entry(self.frame_input, font=("Helvetica", 12), width=20) self.item_entry.grid(row=0, column=3, padx=5) self.category_label = tk.Label( self.frame_input, text="Category:", font=("Helvetica", 12) ) self.category_label.grid(row=0, column=4, padx=5) self.category_dropdown = ttk.Combobox( self.frame_input, textvariable=self.category_var, values=self.categories, font=("Helvetica", 12), width=15, ) self.category_dropdown.grid(row=0, column=5, padx=5) self.date_label = tk.Label( self.frame_input, text="Date (YYYY-MM-DD):", font=("Helvetica", 12) ) self.date_label.grid(row=0, column=6, padx=5) self.date_entry = tk.Entry(self.frame_input, font=("Helvetica", 12), width=15) self.date_entry.grid(row=0, column=7, padx=5)
Define 5 buttons : Add Expense , Edit Expense , Delete Expense , Save Expenses , and Show Expenses Chart . Set the root element for each button, the content it will display, and the command it will run when you click it. Create a frame for the listbox . Set the element's root, font style, and width.
Create a vertical scrollbar and place it on the right side of the canvas. Use it to scroll through the contents of the listbox . Align the entire element with the necessary padding and call update_total_label() .
self.add_button = tk.Button(self, text="Add Expense", command=self.add_expense) self.add_button.pack(pady=5) self.frame_list = tk.Frame(self) self.frame_list.pack(pady=10) self.scrollbar = tk.Scrollbar(self.frame_list) self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.expense_listbox = tk.Listbox( self.frame_list, font=("Helvetica", 12), width=70, yscrollcommand=self.scrollbar.set, ) self.expense_listbox.pack(pady=5) self.scrollbar.config(command=self.expense_listbox.yview) self.edit_button = tk.Button( self, text="Edit Expense", command=self.edit_expense ) self.edit_button.pack(pady=5) self.delete_button = tk.Button( self, text="Delete Expense", command=self.delete_expense ) self.delete_button.pack(pady=5) self.save_button = tk.Button( self, text="Save Expenses", command=self.save_expenses ) self.save_button.pack(pady=5) self.total_label = tk.Label( self, text="Total Expenses:", font=("Helvetica", 12) ) self.total_label.pack(pady=5) self.show_chart_button = tk.Button( self, text="Show Expenses Chart", command=self.show_expenses_chart ) self.show_chart_button.pack(pady=5) self.update_total_label()
Determine the functionality of the expense tracking tool
Define the method, add_expense . Retrieve the value of expenses, items, categories, and dates. If the expense value and date are valid, add the expense to the expenses list . Insert this record into listbox and format it accordingly. Once inserted, clear the user input in the input boxes for the new input.
Otherwise, a warning shows that the value of the cost and date cannot be empty. Call update_total_label .
def add_expense(self): expense = self.expense_entry.get() item = self.item_entry.get() category = self.category_var.get() date = self.date_entry.get() if expense and date: self.expenses.append((expense, item, category, date)) self.expense_listbox.insert( tk.END, f"{expense} - {item} - {category} ({date})" ) self.expense_entry.delete(0, tk.END) self.item_entry.delete(0, tk.END) self.date_entry.delete(0, tk.END) else: messagebox.showwarning("Warning", "Expense and Date cannot be empty.") self.update_total_label()
Define the method, edit_expense . Retrieve the index of the selected record and get the cost. Opens a dialog box asking for expense entry. If the user has provided new costs, change the cost list accordingly. Call refresh_list and update_total_label .
def edit_expense(self): selected_index = self.expense_listbox.curselection() if selected_index: selected_index = selected_index[0] selected_expense = self.expenses[selected_index] new_expense = simpledialog.askstring( "Edit Expense", "Enter new expense:", initialvalue=selected_expense[0] ) if new_expense: self.expenses[selected_index] = ( new_expense, selected_expense[1], selected_expense[2], selected_expense[3], ) self.refresh_list() self.update_total_label()
Define the method, delete_expense . Retrieve the index of the selected record and get the cost. Change the index of the entry you want to delete. Remove that entry from the listbox and call update_total_label .
def delete_expense(self): selected_index = self.expense_listbox.curselection() if selected_index: selected_index = selected_index[0] del self.expenses[selected_index] self.expense_listbox.delete(selected_index) self.update_total_label()
Define method, refresh_list . Delete the current record and add a new record with the updated values.
def refresh_list(self): self.expense_listbox.delete(0, tk.END) for expense, item, category, date in self.expenses: self.expense_listbox.insert( tk.END, f"{expense} - {item} - {category} ({date})" )
Defines the update_total_label method . Total all costs in the list and update it on the label. Define another method, save_expenses . Create and open a CSV file named expenses.csv in write mode. Add the column headers for the CSV file to the first row. Repeat each expense record and write it in a row.
def update_total_label(self): total_expenses = sum(float(expense[0]) for expense in self.expenses) self.total_label.config(text=f"Total Expenses: USD {total_expenses:.2f}") def save_expenses(self): with open("expenses.csv", "w", newline="") as csvfile: writer = csv.writer(csvfile) column_headers = ["Expense Amount", "Item Description", "Category", "Date"] writer.writerow(column_headers) for expense in self.expenses: writer.writerow(expense))
Define a method, show_expenses_chart . Defines a dictionary, category_totals . Loop through the expenses list and convert the expense amount to float. Store total costs for each category. If the category already exists in the dictionary, increase the total to the current cost amount. If not, create a new entry with the current total cost.
def show_expenses_chart(self): category_totals = {} for expense, _, category, _ in self.expenses: try: amount = float(expense) except ValueError: continue category_totals[category] = category_totals.get(category, 0) + amount
Retrieve categories and costs in two different lists. Create a new style for the map with specific dimensions. Create a pie chart, using the expense list as the data and the categories as the labels. The autopct parameter determines the format for displaying percentage values on chart sections. Convert equal to plt.axis to ensure the data you plot is circular. Give the pie chart a title and display it.
categories = list(category_totals.keys()) expenses = list(category_totals.values()) plt.figure(figsize=(8, 6)) plt.pie( expenses, labels=categories, autopct="%1.1f%%", startangle=140, shadow=True ) plt.axis("equal") plt.title(f"Expense Categories Distribution (USD)") plt.show()
Create an instance of ExpenseTrackerApp . The mainloop() function tells Python to loop Tkinter events and listen for them until you close the window.
if __name__ == "__main__": app = ExpenseTrackerApp() app.mainloop()
Check out the various features of an expense management app in Python
When you run this program, it will open an application window. The inside contains input fields for recording costs, item descriptions, categories, and dates. Enter some data and click the Add Expense button . You will see the record added to the list box. This program also updates the total cost.
Select the record and click the Edit Expenses button . A dialog box appears, allowing you to update each record.
Click the Delete Expenses button to remove the selected record.
When the Show Expenses Chart button is pressed , the program displays a pie chart. The pie chart shows the cost for each category along with its name and percentage.
You can add search functionality to allow users to find specific costs based on description, quantity, folder, or date. You can add sorting and filtering options to records. Localize your app to multiple languages and currency formats.
Hope the article is useful to you.
You should read it
- What is Python? Why choose Python?
- 5 choose the best Python IDE for you
- Bookmark 5 best Python programming learning websites
- Multiple choice quiz about Python - Part 3
- Why should you learn Python programming language?
- For in Python loop
- Python data type: string, number, list, tuple, set and dictionary
- Multiple choice quiz about Python - Part 4
May be interested
- Multiple choice quiz about Python - Part 3today's topic quantrimang wants to challenge you is about file and exception handling in python. let's try the following 15 questions!
- 5 choose the best Python IDE for youin order to learn well python, it is essential that you find yourself an appropriate ide to develop. quantrimang would like to introduce some of the best environments to help improve your productivity.
- What is Python? Why choose Python?python is a powerful, high-level, object-oriented programming language, created by guido van rossum. python is easy to learn and emerging as one of the best introductory programming languages for people who are first exposed to programming languages.
- Module time in Pythonpython has a time module used to handle time-related tasks. tipsmake.com will work with you to find out the details and functions related to the time specified in this module. let's follow it!
- Python data type: string, number, list, tuple, set and dictionaryin this section, you'll learn how to use python as a computer, grasp python's data types and take the first step towards python programming.
- How to install Python on Windows, macOS, Linuxto get started with python, you first need to install python on the computer you are using, be it windows, macos or linux. below is a guide to installing python on your computer, specific to each operating system.
- How to set up Python to program on WSLget started with cross-platform python programming by setting up python on the windows subsystem for linux. here's how to set up python for wsl programming.
- Multiple choice quiz about Python - Part 4continue python's thematic quiz, part 4 goes back to the topic core data type - standard data types in python. let's try with quantrimang to try the 10 questions below.
- How to use Closure in Pythonin this article, tipsmake.com will work with you to learn about closure in python, how to define a closure and why you should use it. let's go find the answer!
- Functions in Pythonwhat is python function? how is the syntax, components, and function types in python? how to create functions in python? these questions will be answered in the python lesson below.