1
0

feat: finish legacy project and move it as packaged python project

This commit is contained in:
2026-06-16 20:44:57 +08:00
parent 480e11dbf4
commit a27c5505df
11 changed files with 169 additions and 36 deletions

View File

@@ -0,0 +1,137 @@
import enum
from functools import cached_property
from dataclasses import dataclass
from typing import Iterator
from .common import DeviceKind, Circuit
class ResponsePriority(enum.Enum):
"""
The priority of the result.
"""
LESS_DEVICES = enum.auto()
"""Less devices is the first priority."""
MORE_ACCURACY = enum.auto()
"""More accuracy is the first priority."""
@dataclass
class Request:
"""
All request infomation for the resolver.
"""
device_kind: DeviceKind
"""The kind of device to resolve."""
target_value: float
"""The target value of the device."""
tolerance: float
"""The tolerance of the device in absolute value."""
response_priority: ResponsePriority
"""The priority principle when sorting response items."""
count_limit: int
"""The limited count of results."""
class ResponseItem:
"""
The possible solution given by the resolver.
"""
__circuit: Circuit
"""The circuit of the response item."""
__device_kind: DeviceKind
"""The kind of device of this circuit."""
__target_value: float
"""The target value of this circuit."""
def __init__(
self, circuit: Circuit, device_kind: DeviceKind, target_value: float
) -> None:
self.__circuit = circuit
self.__device_kind = device_kind
self.__target_value = target_value
@property
def circuit(self) -> Circuit:
"""
The circuit of this response item.
:return: The circuit.
"""
return self.circuit
@cached_property
def device_count(self) -> int:
"""
The device count of this circuit.
:return: The device count.
"""
return self.circuit.device_scale.to_device_count()
@cached_property
def value(self) -> float:
"""
The value of this circuit.
:return: The value.
"""
return self.__circuit.compute(self.__device_kind)
@cached_property
def difference(self) -> float:
"""
The absolute difference between the target value and the value of this circuit.
:return: The absolute difference.
"""
return abs(self.__target_value - self.value)
@cached_property
def relative_difference(self) -> float:
"""
The relative difference between the target value and the value of this circuit.
:return: The relative difference.
"""
return self.difference / self.__target_value
class Response:
"""
The collection of possible solutions given by the resolver.
For getting the response items, please use `response[index]`.
For iterating the response items, please use the iterator protocol.
For getting the count of response items, please use the ``len`` function.
"""
__sorted_items: list[ResponseItem]
"""The sorted items by priority and difference."""
def __init__(self, request: Request, candidates: Iterator[Circuit]) -> None:
self.__sorted_items = list(
ResponseItem(item, request.device_kind, request.target_value)
for item in candidates
)
# Sort by different strategy
match request.response_priority:
case ResponsePriority.LESS_DEVICES:
self.__sorted_items.sort(key=lambda x: (x.device_count, x.difference))
case ResponsePriority.MORE_ACCURACY:
self.__sorted_items.sort(key=lambda x: x.difference)
# Cut item by limit
self.__sorted_items = self.__sorted_items[:request.count_limit]
def __getitem__(self, index: int) -> ResponseItem:
return self.__sorted_items[index]
def __len__(self) -> int:
return len(self.__sorted_items)
def __iter__(self) -> Iterator[ResponseItem]:
return iter(self.__sorted_items)