DEV Community

Puneet Khandelwal
Puneet Khandelwal

Posted on

Building a Personalized Habit Tracker with Python and Pandas

I kept losing track of my daily routine. Instead of downloading yet another bloated app, I built a habit tracker in Python using Pandas, SQLite, and Tkinter.

The core requirements were simple: a basic GUI for input, reliable data storage, and a way to visualize completion rates. Tkinter handles the interface, SQLite keeps the data persistent, and Pandas does the heavy lifting for analysis.

import tkinter as tk
from tkinter import messagebox
import sqlite3
import pandas as pd

conn = sqlite3.connect("habits.db")
cur = conn.cursor()

cur.execute("""CREATE TABLE IF NOT EXISTS habits (
 id INTEGER PRIMARY KEY AUTOINCREMENT,
 habit TEXT,
 completed INTEGER
 )""")

cur.execute("""CREATE TABLE IF NOT EXISTS entries (
 id INTEGER PRIMARY KEY AUTOINCREMENT,
 date DATE,
 habit_id INTEGER,
 FOREIGN KEY (habit_id) REFERENCES habits (id)
 )""")

conn.commit()
conn.close()
Enter fullscreen mode Exit fullscreen mode

User inputs hit the database immediately. To check my progress, I wrote a quick processing function that pulls everything into Pandas and plots the results with Matplotlib.

import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime

def process_data():
 conn = sqlite3.connect("habits.db")
 cur = conn.cursor()
 cur.execute("SELECT * FROM habits")
 habits_df = pd.DataFrame(cur.fetchall(), columns=["id", "habit", "completed"])
 cur.execute("SELECT * FROM entries")
 entries_df = pd.DataFrame(cur.fetchall(), columns=["id", "date", "habit_id"])

 merged_df = pd.merge(habits_df, entries_df, on="habit_id")
 completion_rates = merged_df.groupby("habit")["completed"].mean()

 plt.bar(completion_rates.index, completion_rates.values)
 plt.xlabel("Habit")
 plt.ylabel("Completion Rate")
 plt.title("Habit Completion Rates")
 plt.show()

 conn.close()
Enter fullscreen mode Exit fullscreen mode

Looking at actual completion rates changed how I plan my days. Building this tiny tool gave me the accountability I needed without paying for a subscription.

Top comments (0)