Files
cmm-report-analyzer/app/parsers/models.py
chrisryn 9abf9b4b58 Initial commit: CMM Report Analyzer
FastAPI app that parses CMM inspection reports (PDF/Excel/CSV),
computes SPC metrics (Cp/Cpk/Pp/Ppk, control limits, Shapiro-Wilk),
generates interactive Plotly charts, and provides AI-powered quality
summaries via Azure OpenAI with graceful fallback.

Includes 21 passing tests covering parsers, SPC calculations, and
API endpoints.
2026-02-19 10:38:51 -06:00

62 lines
1.7 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, field
@dataclass
class MeasurementRecord:
feature_name: str
nominal: float
tolerance_plus: float
tolerance_minus: float
actual: float
deviation: float = 0.0
unit: str = "mm"
@property
def usl(self) -> float:
return self.nominal + self.tolerance_plus
@property
def lsl(self) -> float:
return self.nominal + self.tolerance_minus # tolerance_minus is negative
@property
def in_tolerance(self) -> bool:
return self.lsl <= self.actual <= self.usl
def to_dict(self) -> dict:
return {
"feature_name": self.feature_name,
"nominal": self.nominal,
"tolerance_plus": self.tolerance_plus,
"tolerance_minus": self.tolerance_minus,
"actual": self.actual,
"deviation": self.deviation,
"unit": self.unit,
"usl": self.usl,
"lsl": self.lsl,
"in_tolerance": self.in_tolerance,
}
@dataclass
class ParsedReport:
filename: str
measurements: list[MeasurementRecord] = field(default_factory=list)
metadata: dict[str, str] = field(default_factory=dict)
raw_text: str = ""
@property
def out_of_tolerance(self) -> list[MeasurementRecord]:
return [m for m in self.measurements if not m.in_tolerance]
def to_dict(self) -> dict:
return {
"filename": self.filename,
"metadata": self.metadata,
"measurement_count": len(self.measurements),
"out_of_tolerance_count": len(self.out_of_tolerance),
"measurements": [m.to_dict() for m in self.measurements],
}