Skip to content

Instantly share code, notes, and snippets.

@architectureman
Last active February 22, 2025 10:30
Show Gist options
  • Select an option

  • Save architectureman/bb35afaa4922539813e4e6a810ac50c6 to your computer and use it in GitHub Desktop.

Select an option

Save architectureman/bb35afaa4922539813e4e6a810ac50c6 to your computer and use it in GitHub Desktop.
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