File size: 3,239 Bytes
a0debed |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
"""
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") |