diff --git a/legacy/src/lcr_connector/__init__.py b/legacy/src/lcr_connector/__init__.py index 65067ae..7bde024 100644 --- a/legacy/src/lcr_connector/__init__.py +++ b/legacy/src/lcr_connector/__init__.py @@ -9,7 +9,7 @@ from .dataset import ( to_human_readable_value, from_human_readable_value, ) -from .query import Request, ResponsePriority, Response +from .query import Request, ResponsePriority, Response, ResponseItem from .resolver import Resolver, LutResolver, BfsResolver _TStrEnum = TypeVar("_TStrEnum", bound=enum.StrEnum) @@ -189,7 +189,7 @@ class App: item.relative_difference, ) ) - self.__illustrate_circuit(item.circuit) + self.__illustrate_circuit(item.circuit, response.device_kind) # print page footer print("") @@ -319,33 +319,98 @@ class App: else: return None - def __get_joint_kind_symbol(self, joint_kind: JointKind) -> str: - match joint_kind: - case JointKind.SERIES: - return "S" - case JointKind.PARALLEL: - return "P" - - def __illustrate_circuit(self, circuit: Circuit) -> None: + def __illustrate_circuit(self, circuit: Circuit, device_kind: DeviceKind) -> None: match circuit.device_scale: case CircuitDeviceScale.ONE: - dev1 = to_human_readable_value(circuit.first_device_value) - print(f"{dev1}") + self.__illustrate_one_device_circuit(circuit, device_kind) case CircuitDeviceScale.TWO: - dev1 = to_human_readable_value(circuit.first_device_value) - j2 = self.__get_joint_kind_symbol(circuit.second_device_joint) - dev2 = to_human_readable_value(circuit.second_device_value) - print(f"[{j2}] ┬ {dev1}") - print(f" └ {dev2}") + self.__illustrate_two_device_circuit(circuit, device_kind) case CircuitDeviceScale.THREE: - dev1 = to_human_readable_value(circuit.first_device_value) - j2 = self.__get_joint_kind_symbol(circuit.second_device_joint) - dev2 = to_human_readable_value(circuit.second_device_value) - j3 = self.__get_joint_kind_symbol(circuit.third_device_joint) - dev3 = to_human_readable_value(circuit.third_device_value) - print(f"[{j3}] ┬ [{j2}] ┬ {dev1}") - print(f" │ └ {dev2}") - print(f" └ {dev3}") + self.__illustrate_three_device_circuit(circuit, device_kind) + + def __get_device_unit(self, device_kind: DeviceKind) -> str: + match device_kind: + case DeviceKind.RESISTOR: + return '\u2126' + case DeviceKind.CAPACITOR: + return 'F' + case DeviceKind.INDUCTOR: + return 'H' + + def __to_circult_graph_value(self, value: float, device_kind: DeviceKind) -> str: + # Remove unit and append device unit + return to_human_readable_value(value)[1:] + self.__get_device_unit(device_kind) + + # YYC MARK: + # The function showing circuit graph should be maintained carefully. + # First, we want they are show in console properly, + # And we also want they have good code view. + # + # I notices that the number part of the output of `to_human_readable_value` will only be + # "+999.9999" or "+9.9999e+00". So its maximum of its length is 11, considering the possibility, + # that the absolute value of exponential part is larger than 99, is close to zero. + # After putting the scale unit and device unit together like " nF", + # the whole maximum size of the built string is 14. + # + # So we need pick a larger number and odd number for the space for showing device value, + # because odd value can be divided by two so it can be split as two parts equally + # for the convenient alignment of some circuit graphs. + # My picked value is 16. + # So you will see that I use `:^16` for a center alignment to given string. + # + # After this, we also need set the padding value carefully. + # This value should consider the length of f-string syntax, pre-defined chars and required chars. + # To make sure a pretty showcase both in code and display. + + def __illustrate_one_device_circuit(self, circuit: Circuit, device_kind: DeviceKind) -> None: + dev1 = self.__to_circult_graph_value(circuit.first_device_value, device_kind) + print(f"──[{dev1:^16}]──") + + def __illustrate_two_device_circuit(self, circuit: Circuit, device_kind: DeviceKind) -> None: + dev1 = self.__to_circult_graph_value(circuit.first_device_value, device_kind) + j2 = circuit.second_device_joint + dev2 = self.__to_circult_graph_value(circuit.second_device_value, device_kind) + match j2: + case JointKind.SERIES: + print(f"──[{dev1:^16}]──[{dev2:^16}]──") + case JointKind.PARALLEL: + SEP0: str = ' ' * (6 + (16 - 10)) + print(f" ┌──[{dev1:^16}]──┐ ") + print(f"──┤ {SEP0} ├──") + print(f" └──[{dev2:^16}]──┘ ") + + def __illustrate_three_device_circuit(self, circuit: Circuit, device_kind: DeviceKind) -> None: + dev1 = self.__to_circult_graph_value(circuit.first_device_value, device_kind) + j2 = circuit.second_device_joint + dev2 = self.__to_circult_graph_value(circuit.second_device_value, device_kind) + j3 = circuit.third_device_joint + dev3 = self.__to_circult_graph_value(circuit.third_device_value, device_kind) + match j2: + case JointKind.SERIES: + match j3: + case JointKind.SERIES: + # All in series + print(f"──[{dev1:^16}]──[{dev2:^16}]──[{dev3:^16}]──") + case JointKind.PARALLEL: + # First series then parallel + SEP0: str = '─' * (6 + ((16 - 10) // 2)) + SEP1: str = ' ' * (6 + 2 * (16 - 10)) + print(f" ┌──[{dev1:^16}]──[{dev2:^16}]──┐ ") + print(f"──┤ {SEP1} ├──") + print(f" └───{SEP0}[{dev3:^16}]{SEP0}───┘ ") + case JointKind.PARALLEL: + match j3: + case JointKind.SERIES: + # First parallel then series + SEP0: str = ' ' * (6 + (16 - 10)) + print(f" {SEP0} ┌──[{dev1:^16}]──┐ ") + print(f"──[{dev1:^16}]──┤ {SEP0} ├──") + print(f" {SEP0} └──[{dev2:^16}]──┘ ") + case JointKind.PARALLEL: + # All in parallel + print(f" ┌──[{dev1:^16}]──┐ ") + print(f"──┼──[{dev2:^16}]──┼──") + print(f" └──[{dev3:^16}]──┘ ") def main() -> None: diff --git a/legacy/src/lcr_connector/query.py b/legacy/src/lcr_connector/query.py index f9dd630..323a1e9 100644 --- a/legacy/src/lcr_connector/query.py +++ b/legacy/src/lcr_connector/query.py @@ -129,11 +129,14 @@ class Response: For getting the count of response items, please use the ``len`` function. """ + __device_kind: DeviceKind + """The kind of device of this response.""" __sorted_items: list[ResponseItem] """The sorted items by priority and difference.""" def __init__(self, request: Request, candidates: Iterable[Circuit]) -> None: cv_trait = CircuitValueTrait(request.device_kind, request.target_value) + self.__device_kind = request.device_kind self.__sorted_items = list( ResponseItem(item, cv_trait) for item in candidates ) @@ -150,6 +153,10 @@ class Response: # Cut item by limit self.__sorted_items = self.__sorted_items[: request.count_limit] + @property + def device_kind(self) -> DeviceKind: + return self.__device_kind + def __getitem__(self, index: int) -> ResponseItem: return self.__sorted_items[index] diff --git a/legacy/src/lcr_connector/resolver/lut.py b/legacy/src/lcr_connector/resolver/lut.py index b399258..797b077 100644 --- a/legacy/src/lcr_connector/resolver/lut.py +++ b/legacy/src/lcr_connector/resolver/lut.py @@ -43,17 +43,18 @@ class LutResolver(Resolver): """The lookup table for inductors.""" def __init__(self, datasets: DatasetCollection): - self.__resistor_lut = self.__build_lut( + self.__resistor_lut = LutResolver.__build_lut( datasets.resistor_values, DeviceKind.RESISTOR ) - self.__capacitor_lut = self.__build_lut( + self.__capacitor_lut = LutResolver.__build_lut( datasets.capacitor_values, DeviceKind.CAPACITOR ) - self.__inductor_lut = self.__build_lut( + self.__inductor_lut = LutResolver.__build_lut( datasets.inductor_values, DeviceKind.INDUCTOR ) - def __build_lut(self, dataset: Dataset, device_kind: DeviceKind) -> list[LutItem]: + @staticmethod + def __build_lut(dataset: Dataset, device_kind: DeviceKind) -> list[LutItem]: lut = [ LutItem(circuit, device_kind) for circuit in chain(