"""Helpers for converting ingredient portions to gram quantities.""" from __future__ import annotations from collections.abc import Sequence from parsing_pipeline.db.usda_ingredient_tables import IngredientPortion def convert_quantity_to_grams_from_portions( portions: Sequence[IngredientPortion], quantity: float, unit: str, ) -> float | None: """Find the first portion whose modifier matches *unit* and return the gram conversion. Matching: normalized modifier equals normalized unit, or unit is a substring of the modifier (e.g. "cup" matches "cup, chopped"). Returns ``(quantity / portion.amount) * portion.gram_weight`` on match, else None. """ normalized_unit = unit.strip().lower() for portion in portions: if portion.amount is None or portion.amount <= 0: continue if portion.gram_weight <= 0: continue portion_modifier = (portion.modifier or "").strip().lower() if portion_modifier == normalized_unit or normalized_unit in portion_modifier: return (quantity / portion.amount) * portion.gram_weight return None