Note · Finance & Shopping
Predicting my shopping list from receipts
Combining voice-added Google Keep items with automatic suggestions predicted from digital supermarket receipts.

The main way I add things to my shopping list is by voice: when I finish the olive oil or run out of coffee beans, I ask my Echo Dot voice assistant to add it, which drops the item straight into Google Keep through Home Assistant. That works well for things I notice running out in the kitchen, but I kept coming home from my weekly shop having forgotten at least one staple I buy almost every week.
Because I do nearly all of my grocery shopping at the same supermarket, every trip produces an itemised digital receipt (the same receipt history that feeds my fitness coach’s nutrition estimates and my finance dashboard). Instead of asking an LLM to guess what I need, we built a small deterministic model in Python that learns my buying intervals from those receipts and appends due staples to the bottom of my Google Keep list.
Teaching the model that any eggs count as eggs
Raw till receipts are too messy to track by product name alone. Some lines arrive as truncated camelCase strings (RSPCAUnsmokBackBacon, SweetPicklePiccallil), and the supermarket occasionally reuses the same 7-digit article code for completely different seasonal products.
Even when the codes behave, I don’t care whether I bought medium or large eggs, or regular versus tenderstem broccoli. Early on, buying a different box size split the purchase history in two and made the model think both were overdue.
We fixed that by grouping receipt lines into 34 product families before calculating any intervals. A normaliser splits run-together words, checks token overlap before trusting a reused article code, and collapses variants so any eggs count as Eggs, any rashers count as Bacon, and any broccoli counts as Broccoli, while keeping look-alikes like salted butter and peanut butter separate.
Suggesting for this week, not after it’s overdue
For each product family, the model calculates the median number of days between purchases. Originally, it only flagged an item once days_since >= median_days.
Because I usually do one big shop on a Monday, that rule failed on weekly staples. An item with a 7-day cadence bought last Monday was only 6 days old on Sunday night, so it stayed hidden until after I’d already been to the shop.
Changing the gate to look seven days ahead (days_since + 7 >= median_days) fixed the timing. Now the model surfaces staples whose next purchase falls inside the coming week. If I stop buying something altogether, it ages out after two missed cycles so old habits don’t linger at the top of the list forever.
Writing into Google Keep without wrecking my list
I didn’t want a second shopping app to check while standing in the aisle. The app’s scheduler pulls my live Google Keep list twice a day through Home Assistant’s todo integration and compares it against the upcoming staples.
That comparison uses the same product-family aliases as the receipt parser, tuned for how I actually speak to the voice assistant: if I’ve already asked the Echo Dot to add Berries or Milk, the reconciler knows Blueberries and Oat drink are covered and skips them. Anything genuinely missing gets appended to the bottom as Suggested: <item>.
Because it shares a list with my voice-added and typed items, the reconciler follows strict ownership rules:
- UID tracking: it records the exact remote item ID of every suggestion it creates, and never modifies or deletes manual entries.
- Hands off if edited: if I rename a suggested line, the reconciler drops ownership and leaves it alone.
- No nagging: if I tick a suggestion off or delete it, that product family is suppressed for 14 days so the next sync doesn’t immediately put it back.
- No self-reinforcing loop: generated lines are excluded when the model snapshots my list, so the predictor never treats its own output as proof that I planned to buy something.
When I get to the shop and open Google Keep, the things I asked the Echo Dot to add during the week and the staples the receipt model noticed I was due for are already sitting in one list.