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")