Project Detail

Workout Tracker

I built a natural language workout logger that writes directly to Google Sheets. You type a plain-English description of your session and the app handles the rest — a locally-running LLM (llama3.2 via Ollama) parses the exercise name and duration, calories are computed using the standard MET formula, and each exercise is logged as a timestamped row via the Sheety REST API. Built as Day 38 of 100 Days of Code, then significantly extended after the original API dependency was discontinued mid-development.

Software LLM API-integration authentication automation CLI OOP productivity python REST-API terminal-ux

Quick Facts

Tech:
Python Ollama llama3.2 Sheety API Google Sheets requests python-dotenv

Overview

Problem

Tracking workouts manually is tedious enough that most people stop doing it. You finish a session, open a spreadsheet, try to remember how long each exercise took, estimate the calories, type it all in — and after a few sessions you've already given up. The course solution used Nutritionix for natural language parsing, but Nutritionix discontinued its free tier during development, breaking the core feature entirely and forcing me to rethink the architecture from scratch.

Solution

I replaced Nutritionix with a locally-running LLM via Ollama — no API key, no account, no cost, works offline. The user types a free-form workout description; llama3.2 extracts the exercise name and duration as structured JSON; a built-in MET table calculates calories deterministically; and the Sheety API writes each exercise as a new row in Google Sheets with Basic Auth. I added a synonym map to normalise variant names (jogging → Running, swam → Swimming), a disambiguation prompt for vague inputs like "went to the gym", and a session loop so an entire workout can be logged without returning to the menu.

Challenges

Nutritionix discontinued its free tier mid-project, eliminating the only free cloud API that handled natural language → structured exercise data in one call. Every alternative required structured input, and the constraint — free for anyone who clones the repo, no sign-ups — ruled out paid replacements. I switched to Ollama and kept the natural language UX intact. The next issue was calorie accuracy: the LLM returned inconsistent numbers for the same exercise on different runs. I removed calorie estimation from the model entirely and calculated it locally using the MET formula instead. I also had to fix name consistency — the model kept returning past-tense verbs like "Swam" and "Ran", causing duplicate entries in the sheet. I solved this with prompt engineering and a deterministic synonym map as a fallback. Finally, vague inputs like "went to the gym" caused the model to guess randomly, so I built a pre-Ollama disambiguation step that detects trigger words, presents 19 gym-specific options, extracts any duration already mentioned in the input via regex, and rewrites the query before sending it to the model.

Results / Metrics

I ended up with a fully working natural language workout logger that's free for any user with no configuration beyond Sheety credentials. The project went well beyond the course scope — I had to solve a real API discontinuation, rethink the calorie calculation approach, and engineer around LLM unreliability. It demonstrates OOP module design, REST API integration, local LLM orchestration, prompt engineering, MET-based scientific calculation, and regex input parsing, all built in response to constraints that emerged during development rather than planned upfront.

Screenshots

Click to enlarge.

Click to enlarge.

Videos