Inspiration

Our inspiration came from FoodPharmer, an Instagram creator who calls out packaged food brands for misleading marketing — products labeled as "healthy" or "natural" that turn out to be loaded with added sugar or low-quality ingredients once you actually read the label. He'll take something like a "real fruit juice" marketed as a healthy kids' drink and show, ingredient by ingredient, why that claim doesn't hold up.

The problem: he covers a huge number of products, but that content lives across hundreds of Instagram posts. If you're standing in a store trying to decide on a specific product, scrolling through someone's Instagram to find that one review isn't realistic. We wanted that same "read the actual label, not the marketing" instinct, but instant and searchable — an app built specifically for Indian packaged foods, not a feed you have to scroll through.

What it does

Sugarcoated analyzes Indian packaged food products — either searched from a catalog or pasted as a raw ingredient list — and gives back:

Healthscore (/10): flags specific risky ingredients against a curated severity table, with the reasoning shown, not hidden Macros: each nutrient shown as a percentage of your personal daily limit (BMR-personalized if you share your stats, standard public health guidance otherwise), plus a protein-per-fat efficiency comparison against similar products Dietician: checks the product against vegan, diabetic-friendly, low-sodium, or gluten-free profiles, with the specific reason it passes or fails Alternates: same-category product suggestions that score better, are more nutrient-efficient, or actually pass your diet profile — each shown with a real product photo (pulled from Open Food Facts) or a category icon fallback, a plain-language "why it's better" comparison, and one-tap search links to Blinkit and Zepto so you can actually go find it Personalized targets: an optional intake step (weight, height, age, gender) calculates your BMR via the Mifflin-St Jeor formula so the Macros tab compares nutrients against your daily targets, not just generic population averages Fuzzy typo handling: a misspelled ingredient like "PLOtein" still gets matched to "Protein," and the match is shown transparently rather than silently guessed

How we built it

We started with a much bigger scope — live OpenFoodFacts integration, OCR label scanning, an ML classification layer — and deliberately cut all three once we scoped out the actual time we had. What's left is a two-stage architecture:

Offline pipeline (build_dataset.py): runs once, takes a static CSV of 852 Indian packaged products plus a curated ~52-ingredient red-flag table, and pre-computes a scored products.json. Runtime app (Streamlit): reads that pre-computed catalog for search mode, and runs the same matching/scoring logic live for pasted custom ingredients — no duplicated logic between the two paths.

A single shared alternates function powers recommendations across all three tabs (same category, different sort key per tab), rather than three separate copy-pasted filters. Nutrient limits are pulled from WHO, ICMR, and FSSAI published guidance rather than invented thresholds. Product images are fetched from the Open Food Facts API (used only for display, cached locally, with a category-icon fallback when no match exists) — we deliberately kept this separate from our scoring pipeline, so an image lookup failing never affects the actual health analysis. Since we don't have access to real-time inventory or pricing APIs from quick-commerce platforms, "buy this instead" links are constructed as direct search-query URLs to Blinkit and Zepto rather than fake or guessed product links.

Challenges we ran into

Silent failure modes are worse than crashes. Early on, custom-pasted ingredients with a typo just silently failed to match, with no indication anything went wrong. We rebuilt matching to fall back to fuzzy similarity scoring, and made sure every fuzzy correction is shown to the user rather than hidden. The "quantities vs. FSSAI limit" idea we originally wanted turned out not to be feasible — Indian ingredient lists don't carry exact quantities, and FSSAI doesn't publish per-ingredient numeric caps in a usable form. We pivoted to comparing actual nutrient columns (sugar, sodium, fat) against real published daily guidance instead, which is both more honest and more actionable. Duplicated logic between the offline pipeline and the live app was a real bug risk we caught and fixed — one shared matching module now serves both, so a fix in one place can't silently desync from the other. Graceful degradation, not crashes, when data is missing — e.g. a custom ingredient paste with no nutrition info entered shows an honest "not enough data" message on the Macros tab instead of blank output or a stack trace.

Accomplishments that we're proud of

We caught and fixed a real duplicated-logic bug before it shipped — our offline pipeline and live custom-ingredient path were running separate copies of the matching logic, which could've silently desynced. One shared module now powers both. We also built fuzzy typo-tolerance into ingredient matching (a misspelled "PLOtein" still resolves to "Protein," shown transparently, not silently), and a single reusable alternates engine that powers recommendations across all three tabs instead of three duplicated filters. Proudest of all: we scoped down hard mid-build — cutting OCR, live OpenFoodFacts lookup, and ML — and still shipped something that's fully explainable end to end, with zero black-box scoring.

What we learned

Cutting scope early (dropping OCR and live API calls) was the right call — it kept the core rule-based engine reliable and fully explainable instead of chasing three half-working features. We also learned that "showing your reasoning" (fuzzy match confidence, specific pass/fail reasons, exact severity per ingredient) builds far more trust than a single opaque score ever could.

What's next for Sugarcoated?

Expanding catalog coverage beyond 852 products, revisiting OCR for label photo input now that the core scoring engine is solid, and potentially layering in a live OpenFoodFacts lookup as a fallback when a searched product isn't in the local catalog.

Built With

Share this project:

Updates

Submission history