feat: finish legacy project and move it as packaged python project
This commit is contained in:
137
legacy/src/lcr_connector/query.py
Normal file
137
legacy/src/lcr_connector/query.py
Normal 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)
|
||||
Reference in New Issue
Block a user