1455 words
7 minutes
Building a Dev Productivity Tracker in Python with SQLite and Matplotlib

Building a Developer Productivity Tracker in Python with SQLite and Matplotlib#

Understanding and improving development workflows often benefits from data-driven insights. Tracking how time is spent on different tasks, identifying interruptions, and analyzing work patterns can lead to greater efficiency and focus. A simple yet effective tool for this can be built using fundamental programming concepts and readily available libraries.

This article outlines the process of constructing a basic developer productivity tracker. The chosen tools – Python, SQLite, and Matplotlib – offer a powerful combination: Python for scripting logic and data manipulation, SQLite for simple, file-based data storage, and Matplotlib for generating informative visualizations from the collected data.

Core Concepts of Productivity Tracking#

Developer productivity is not solely measured by lines of code, but rather by the successful completion of tasks and delivery of value. Tracking aims to provide visibility into work patterns, helping individuals understand where their time is allocated and identify opportunities for optimization.

  • Time Allocation: Recording time spent on specific tasks (coding, meetings, planning, research, breaks) provides a breakdown of work activities.
  • Task Categorization: Grouping tasks helps identify trends across different types of work. Categories might include development, testing, documentation, communication, administration, or learning.
  • Focused vs. Interrupted Time: Distinguishing between periods of deep work and fragmented time helps reveal potential distractions or context-switching overheads.
  • Data for Reflection: The collected data serves as a basis for personal review, enabling developers to reflect on their day or week and make informed adjustments to their work habits.

Python offers flexibility for scripting the tracker’s logic. SQLite provides a lightweight, serverless database ideal for personal use or small projects, storing data persistently in a single file. Matplotlib is a comprehensive plotting library for creating static, interactive, and animated visualizations in Python.

Building the Tracker: A Step-by-Step Guide#

Creating a developer productivity tracker involves setting up the environment, designing the data structure, building the data entry mechanism, and developing analysis and visualization capabilities.

Step 1: Environment Setup#

Building the tracker requires Python installed on the system. The standard Python distribution includes the sqlite3 module for interacting with SQLite databases. The matplotlib library needs to be installed separately.

Terminal window
pip install matplotlib

This command installs the necessary plotting library.

Step 2: Database Design#

A simple database structure is sufficient for tracking basic task information. An SQLite database file will store records of tasks with start and end times. A table named tasks can hold this information.

ColumnData TypeDescription
idINTEGERUnique identifier (primary key)
task_descriptionTEXTBrief description of the task
categoryTEXTCategory of the task (e.g., ‘Code’, ‘Meeting’)
start_timeTEXTTimestamp when the task started
end_timeTEXTTimestamp when the task ended (NULL if ongoing)

The sqlite3 module in Python can be used to create the database and the table.

import sqlite3
import datetime
def create_database(db_name="productivity_tracker.db"):
"""Creates the SQLite database and the tasks table if they don't exist."""
conn = sqlite3.connect(db_name)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_description TEXT NOT NULL,
category TEXT,
start_time TEXT NOT NULL,
end_time TEXT
)
''')
conn.commit()
conn.close()
print(f"Database '{db_name}' and table 'tasks' ensured.")
# Example usage:
# create_database()

This script initializes the database file and the tasks table upon first execution.

Step 3: Data Entry - Recording Tasks#

The core functionality involves recording the start and end times of activities. Python functions can handle interactions with the SQLite database to insert new task records and update existing ones.

import sqlite3
import datetime
DB_NAME = "productivity_tracker.db"
def start_task(description, category="General"):
"""Records the start time of a new task."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# End any potentially ongoing task first (simple approach for personal use)
cursor.execute("UPDATE tasks SET end_time = ? WHERE end_time IS NULL", (now,))
cursor.execute("INSERT INTO tasks (task_description, category, start_time, end_time) VALUES (?, ?, ?, NULL)",
(description, category, now))
conn.commit()
conn.close()
print(f"Started task: '{description}' ({category}) at {now}")
def end_task():
"""Records the end time of the currently active task."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# Find the latest task that is still ongoing (end_time IS NULL)
cursor.execute("UPDATE tasks SET end_time = ? WHERE end_time IS NULL", (now,))
if cursor.rowcount == 0:
print("No active task found to end.")
else:
conn.commit()
print(f"Ended active task at {now}")
conn.close()
def list_tasks(limit=10):
"""Lists the most recent tasks."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("SELECT id, task_description, category, start_time, end_time FROM tasks ORDER BY start_time DESC LIMIT ?", (limit,))
tasks = cursor.fetchall()
conn.close()
if not tasks:
print("No tasks recorded yet.")
return
print("\n--- Recent Tasks ---")
for task in tasks:
task_id, desc, cat, start, end = task
duration = "Ongoing"
if end:
start_dt = datetime.datetime.strptime(start, '%Y-%m-%d %H:%M:%S')
end_dt = datetime.datetime.strptime(end, '%Y-%m-%d %H:%M:%S')
duration_td = end_dt - start_dt
duration = str(duration_td).split('.')[0] # Remove microseconds
print(f"[{task_id}] {desc} ({cat}) | Started: {start} | Ended: {end if end else 'Ongoing'} | Duration: {duration}")
print("--------------------")
# Example Usage (could be wrapped in a command-line interface)
# create_database() # Ensure DB exists first
# start_task("Write Python code for tracker", "Development")
# # ... do work ...
# end_task()
# start_task("Attend stand-up meeting", "Meeting")
# # ... meeting ends ...
# end_task()
# list_tasks()

These functions provide the basic interface for marking the beginning and end of activities. A simple command-line loop or a basic graphical interface could call these functions based on user input.

Step 4: Data Analysis and Visualization#

Once sufficient data is collected, analysis provides insights. Calculating the duration of tasks and aggregating time spent by category reveals patterns. Matplotlib is used to visualize this aggregated data.

import sqlite3
import datetime
import matplotlib.pyplot as plt
from collections import defaultdict
DB_NAME = "productivity_tracker.db"
def analyze_productivity_by_category():
"""Analyzes and visualizes time spent per task category."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
# Select tasks with both start and end times
cursor.execute("SELECT category, start_time, end_time FROM tasks WHERE end_time IS NOT NULL")
completed_tasks = cursor.fetchall()
conn.close()
if not completed_tasks:
print("No completed tasks available for analysis.")
return
time_by_category = defaultdict(datetime.timedelta)
for category, start_str, end_str in completed_tasks:
try:
start_dt = datetime.datetime.strptime(start_str, '%Y-%m-%d %H:%M:%S')
end_dt = datetime.datetime.strptime(end_str, '%Y-%m-%d %H:%M:%S')
duration = end_dt - start_dt
if duration > datetime.timedelta(0): # Only count positive durations
time_by_category[category] += duration
except ValueError:
print(f"Skipping record with invalid timestamp format: Start={start_str}, End={end_str}")
if not time_by_category:
print("No valid completed tasks found for analysis after processing durations.")
return
# Convert timedeltas to hours for easier visualization
hours_by_category = {cat: td.total_seconds() / 3600 for cat, td in time_by_category.items()}
# Prepare data for plotting
categories = list(hours_by_category.keys())
hours = list(hours_by_category.values())
# Sort categories by time spent
sorted_categories, sorted_hours = zip(*sorted(zip(categories, hours), key=lambda x: x[1], reverse=True))
# Create visualization using Matplotlib
plt.figure(figsize=(10, 6))
plt.bar(sorted_categories, sorted_hours, color='skyblue')
plt.xlabel("Task Category")
plt.ylabel("Time Spent (Hours)")
plt.title("Developer Time Allocation by Category")
plt.xticks(rotation=45, ha='right')
plt.tight_layout() # Adjust layout to prevent labels overlapping
plt.show()
# Example usage:
# create_database() # Ensure DB exists
# # ... use start_task() and end_task() to record data ...
# analyze_productivity_by_category()

This script queries completed tasks, calculates their durations, aggregates the time by category, and generates a bar chart showing the total hours spent in each category. This visualization provides a clear overview of where time is being allocated.

Real-World Application and Insights#

A developer productivity tracker built with Python, SQLite, and Matplotlib offers practical benefits for personal workflow improvement.

  • Identifying Time Sinks: By visualizing time spent, developers can pinpoint activities or categories consuming disproportionately large amounts of time, potentially areas where efficiency can be improved or time reduced.
  • Understanding Work Patterns: Analysis of start/end times and durations over days or weeks can reveal patterns in focus levels, optimal working hours, or frequency of context switching.
  • Informing Planning: Data on how long similar tasks actually take provides more accurate estimates for future planning and task breakdown.
  • Personal Goal Setting: Tracking progress allows individuals to set goals for allocating more time to high-value activities or reducing time spent on distractions or low-priority work.

For instance, a visualization might show that “Meeting” and “Administration” categories consume a significant portion of the week, while dedicated “Coding” time is fragmented. This insight could prompt a developer to explore strategies for reducing meeting times, batching administrative tasks, or scheduling focused coding blocks.

While this basic tracker focuses on time per category, it lays the groundwork for more sophisticated analysis, such as tracking time per project, identifying interruptions (periods between tasks), or analyzing productivity variations throughout the day or week.

Key Takeaways#

Building a developer productivity tracker using Python, SQLite, and Matplotlib provides a valuable tool for personal workflow analysis.

  • Python’s scripting capabilities handle data entry and processing logic.
  • SQLite offers a simple, file-based database solution for persistent data storage without requiring a separate database server.
  • Matplotlib enables the creation of clear visualizations from collected data, making it easy to understand time allocation patterns.
  • Tracking provides data-driven insights into work habits, helping identify time sinks and areas for improved focus or efficiency.
  • The modular nature of the Python scripts allows for future expansion, such as adding more detailed task information, different analysis metrics, or more complex visualizations.

Utilizing such a tool can empower developers with empirical data to make conscious decisions about managing their time and improving their productivity.

Building a Dev Productivity Tracker in Python with SQLite and Matplotlib
https://dev-resources.site/posts/building-a-dev-productivity-tracker-in-python-with-sqlite-and-matplotlib/
Author
Dev-Resources
Published at
2025-06-29
License
CC BY-NC-SA 4.0