Last active
February 22, 2025 10:30
-
-
Save architectureman/bb35afaa4922539813e4e6a810ac50c6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from decimal import Decimal, getcontext | |
| from pydantic import BaseModel, field_validator, model_validator, ValidationError | |
| # Thiết lập độ chính xác cho Decimal (ví dụ: 10 chữ số thập phân) | |
| getcontext().prec = 10 | |
| class AllocationModel(BaseModel): | |
| allocations: list[Decimal] | |
| @model_validator(mode='after') | |
| def validate_allocations_sum(self) -> 'AllocationModel': | |
| total = sum(self.allocations) | |
| # Nếu tổng khác 1, hiệu chỉnh giá trị cuối cùng | |
| if total != Decimal('1'): | |
| # Tính sai số và điều chỉnh vào phần tử cuối | |
| error = Decimal('1') - total | |
| self.allocations[-1] += error | |
| # Kiểm tra lại sau khi điều chỉnh | |
| new_total = sum(self.allocations) | |
| if abs(new_total - Decimal('1')) > Decimal('1e-10'): | |
| raise ValueError(f"Tổng allocations phải bằng 1. Hiện tại: {new_total}") | |
| return self | |
| @field_validator('allocations', mode='before') | |
| @classmethod | |
| def parse_allocations(cls, value: list) -> list[Decimal]: | |
| # Chuyển đổi đầu vào sang Decimal để tránh lỗi float | |
| return [Decimal(str(x)) for x in value] | |
| # Case 1: Tổng đúng | |
| try: | |
| model = AllocationModel(allocations=[Decimal('0.3'), Decimal('0.3'), Decimal('0.4')]) | |
| print(model.allocations, "=> Tổng:", sum(model.allocations)) | |
| except ValidationError as e: | |
| print(e) | |
| # Case 2: Tổng sai (0.999999) | |
| try: | |
| model = AllocationModel(allocations=[Decimal('0.333333'), Decimal('0.333333'), Decimal('0.333333')]) | |
| print(model.allocations, "=> Tổng:", sum(model.allocations)) | |
| except ValidationError as e: | |
| print(e) | |
| # Case 3: Đầu vào là float (cần chuyển sang Decimal qua validator) | |
| try: | |
| model = AllocationModel(allocations=[0.32, 0.22, 0.4]) | |
| print(model.allocations, "=> Tổng:", sum(model.allocations)) | |
| except ValidationError as e: | |
| print(e) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment