abhinavvathadi's picture
Initial commit for DealSight Intelligence
76562dd
Raw
History Blame Contribute Delete
2.73 kB
"""The `Item` dataclass: one priced product as it flows through the pipeline.
`Item` exposes a `text` view (cleaned product description) and a `prompt`
view (the question/answer string used during fine-tuning and evaluation).
"""
from __future__ import annotations
import re
from dataclasses import dataclass
from typing import Optional, Self
MIN_CHARS = 300
CEILING_CHARS = 160 * 7
PREFIX = "Price is $"
QUESTION = "How much does this cost to the nearest dollar?"
@dataclass
class Item:
title: str
price: float
description: str = ""
features: list[str] | None = None
details: dict[str, str] | None = None
category: str = "Unknown"
full: Optional[str] = None
weight: Optional[float] = None
summary: Optional[str] = None
saved_prompt: Optional[str] = None
id: Optional[int] = None
@property
def text(self) -> str:
if self.summary:
return clean_text(self.summary)
if self.full:
return clean_text(self.full)[:CEILING_CHARS].rsplit(" ", 1)[0]
features = self.features or []
details = self.details or {}
pieces = [self.title, self.description, " ".join(features), " ".join(details.values())]
cleaned = clean_text(" ".join(piece for piece in pieces if piece))
return cleaned[:CEILING_CHARS].rsplit(" ", 1)[0]
@property
def prompt(self) -> str:
if self.saved_prompt:
return self.saved_prompt
return f"{QUESTION}\n\n{self.text}\n\n{PREFIX}{round(self.price)}.00"
@property
def test_prompt(self) -> str:
return self.prompt.split(PREFIX)[0] + PREFIX
def is_valid(self) -> bool:
return self.price > 0 and len(self.text) >= MIN_CHARS
@classmethod
def from_hub(cls, dataset_name: str) -> tuple[list[Self], list[Self], list[Self]]:
from dealsight_intelligence.data.datasets import load_structured_items
return load_structured_items(dataset_name)
@classmethod
def from_mapping(cls, row) -> Self:
return cls(
title=row.get("title") or "",
description=row.get("description") or "",
features=row.get("features") or [],
details=row.get("details") or {},
price=float(row.get("price") or 0),
category=row.get("category") or "Unknown",
full=row.get("full"),
weight=row.get("weight"),
summary=row.get("summary"),
saved_prompt=row.get("prompt"),
id=row.get("id"),
)
def clean_text(value: str) -> str:
value = re.sub(r"[\r\n\t]+", " ", value)
value = re.sub(r"\s+", " ", value)
value = re.sub(r"\b[A-Z0-9]{8,}\b", " ", value)
return value.strip()