proportio / models.py
grasant's picture
Upload 15 files
a0debed verified
"""
Pydantic models for proportion calculation inputs and outputs.
Provides robust validation and clear error messages.
"""
from typing import Optional
from pydantic import BaseModel, Field, model_validator
class PercentOfInput(BaseModel):
"""Input for calculating what percentage part is of whole."""
part: float = Field(description="The part value")
whole: float = Field(description="The whole value (must not be zero)")
class PercentOfOutput(BaseModel):
"""Output for percentage calculation."""
percentage: float = Field(description="The calculated percentage")
class ProportionInput(BaseModel):
"""Input for solving proportion a/b = c/d with exactly one missing value."""
a: Optional[float] = Field(None, description="First numerator")
b: Optional[float] = Field(None, description="First denominator")
c: Optional[float] = Field(None, description="Second numerator")
d: Optional[float] = Field(None, description="Second denominator")
@model_validator(mode='after')
def validate_exactly_one_none(self) -> 'ProportionInput':
"""Ensure exactly one value is None (missing)."""
values = [self.a, self.b, self.c, self.d]
none_count = sum(1 for v in values if v is None)
assert none_count == 1, "Exactly one value must be None (missing) to solve proportion"
return self
class ProportionOutput(BaseModel):
"""Output for proportion calculation."""
missing: float = Field(description="The calculated missing value")
class ScaleByRatioInput(BaseModel):
"""Input for scaling a value by a ratio."""
value: float = Field(description="The value to scale")
ratio: float = Field(description="The scaling ratio")
class ScaleByRatioOutput(BaseModel):
"""Output for ratio scaling."""
result: float = Field(description="The scaled result")
class DirectKInput(BaseModel):
"""Input for finding constant of proportionality k in y = kx."""
x: float = Field(description="The x value (cannot be zero)")
y: float = Field(description="The y value")
class DirectKOutput(BaseModel):
"""Output for proportionality constant calculation."""
k: float = Field(description="The proportionality constant")
class ResizeDimensionsInput(BaseModel):
"""Input for resizing dimensions with uniform scale factor."""
width: float = Field(description="Original width (must be non-negative)")
height: float = Field(description="Original height (must be non-negative)")
scale: float = Field(description="Scale factor (must be positive)")
class ResizeDimensionsOutput(BaseModel):
"""Output for dimension resizing."""
new_width: float = Field(description="The new width after scaling")
new_height: float = Field(description="The new height after scaling")
# Error response model for consistent error handling
class ErrorResponse(BaseModel):
"""Standard error response format."""
error: str = Field(description="Error message")
detail: Optional[str] = Field(None, description="Additional error details")