Expense Tracker with SQLite
This utility is a command-line expense tracker that stores data in a local SQLite database. It allows you to add, view, and delete expenses, providing a persistent record of your spending without needing a complex server setup.
Modules Used:
- sqlite3: To interact with the SQLite database.
- argparse: To handle command-line arguments.
datetime: To timestamp entries.
The Code
Save this as expense_tracker.py.
import sqlite3
import argparse
from datetime import datetime
import sys
DB_NAME = "expenses.db"
def init_db():
"""Initialize the database and create the table if it doesn't exist."""
conn = sqlite3.connect(DB_NAME)
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS expenses
(id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT,
category TEXT,
amount REAL,
description TEXT)''')
conn.commit()
conn.close()
def add_expense(amount, category, description):
conn = sqlite3.connect(DB_NAME)
c = conn.cursor()
date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
c.execute("INSERT INTO expenses (date, category, amount, description) VALUES (?, ?, ?, ?)",
(date, category, amount, description))
conn.commit()
conn.close()
print(f"Added: ${amount:.2f} for {category}")
def view_expenses(category=None):
conn = sqlite3.connect(DB_NAME)
c = conn.cursor()
if category:
c.execute("SELECT * FROM expenses WHERE category = ?", (category,))
else:
c.execute("SELECT * FROM expenses")
rows = c.fetchall()
conn.close()
if not rows:
print("No expenses found.")
return
print(f"{'ID':<5} {'Date':<20} {'Category':<15} {'Amount':<10} {'Description'}")
print("-" * 70)
total = 0
for row in rows:
# row: (id, date, category, amount, description)
print(f"{row[0]:<5} {row[1]:<20} {row[2]:<15} ${row[3]:<9.2f} {row[4]}")
total += row[3]
print("-" * 70)
print(f"Total: ${total:.2f}")
def delete_expense(expense_id):
conn = sqlite3.connect(DB_NAME)
c = conn.cursor()
c.execute("DELETE FROM expenses WHERE id = ?", (expense_id,))
if c.rowcount > 0:
print(f"Expense {expense_id} deleted.")
else:
print(f"Expense {expense_id} not found.")
conn.commit()
conn.close()
if __name__ == "__main__":
init_db()
parser = argparse.ArgumentParser(description="Simple Expense Tracker")
subparsers = parser.add_subparsers(dest="command", help="Command to run")
# Add Command
add_parser = subparsers.add_parser("add", help="Add a new expense")
add_parser.add_argument("amount", type=float, help="Amount spent")
add_parser.add_argument("category", help="Category (e.g., Food, Transport)")
add_parser.add_argument("description", help="Description of the expense")
# View Command
view_parser = subparsers.add_parser("view", help="View expenses")
view_parser.add_argument("--category", help="Filter by category")
# Delete Command
del_parser = subparsers.add_parser("delete", help="Delete an expense")
del_parser.add_argument("id", type=int, help="ID of the expense to delete")
args = parser.parse_args()
if args.command == "add":
add_expense(args.amount, args.category, args.description)
elif args.command == "view":
view_expenses(args.category)
elif args.command == "delete":
delete_expense(args.id)
else:
parser.print_help()
Usage
# Add expenses
python expense_tracker.py add 15.50 Food "Lunch at diner"
python expense_tracker.py add 50.00 Transport "Gas"
# View all expenses
python expense_tracker.py view
# View only Food expenses
python expense_tracker.py view --category Food
# Delete an expense by ID (find ID from view command)
python expense_tracker.py delete 1