1
0

feat: update circuit display in cli

This commit is contained in:
2026-06-27 23:28:30 +08:00
parent 3bec73b718
commit 5b3a2c030d
3 changed files with 102 additions and 29 deletions

View File

@@ -9,7 +9,7 @@ from .dataset import (
to_human_readable_value, to_human_readable_value,
from_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 from .resolver import Resolver, LutResolver, BfsResolver
_TStrEnum = TypeVar("_TStrEnum", bound=enum.StrEnum) _TStrEnum = TypeVar("_TStrEnum", bound=enum.StrEnum)
@@ -189,7 +189,7 @@ class App:
item.relative_difference, item.relative_difference,
) )
) )
self.__illustrate_circuit(item.circuit) self.__illustrate_circuit(item.circuit, response.device_kind)
# print page footer # print page footer
print("") print("")
@@ -319,33 +319,98 @@ class App:
else: else:
return None return None
def __get_joint_kind_symbol(self, joint_kind: JointKind) -> str: def __illustrate_circuit(self, circuit: Circuit, device_kind: DeviceKind) -> None:
match joint_kind:
case JointKind.SERIES:
return "S"
case JointKind.PARALLEL:
return "P"
def __illustrate_circuit(self, circuit: Circuit) -> None:
match circuit.device_scale: match circuit.device_scale:
case CircuitDeviceScale.ONE: case CircuitDeviceScale.ONE:
dev1 = to_human_readable_value(circuit.first_device_value) self.__illustrate_one_device_circuit(circuit, device_kind)
print(f"{dev1}")
case CircuitDeviceScale.TWO: case CircuitDeviceScale.TWO:
dev1 = to_human_readable_value(circuit.first_device_value) self.__illustrate_two_device_circuit(circuit, device_kind)
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}")
case CircuitDeviceScale.THREE: case CircuitDeviceScale.THREE:
dev1 = to_human_readable_value(circuit.first_device_value) self.__illustrate_three_device_circuit(circuit, device_kind)
j2 = self.__get_joint_kind_symbol(circuit.second_device_joint)
dev2 = to_human_readable_value(circuit.second_device_value) def __get_device_unit(self, device_kind: DeviceKind) -> str:
j3 = self.__get_joint_kind_symbol(circuit.third_device_joint) match device_kind:
dev3 = to_human_readable_value(circuit.third_device_value) case DeviceKind.RESISTOR:
print(f"[{j3}] ┬ [{j2}] ┬ {dev1}") return '\u2126'
print(f" │ └ {dev2}") case DeviceKind.CAPACITOR:
print(f"{dev3}") 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: def main() -> None:

View File

@@ -129,11 +129,14 @@ class Response:
For getting the count of response items, please use the ``len`` function. 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] __sorted_items: list[ResponseItem]
"""The sorted items by priority and difference.""" """The sorted items by priority and difference."""
def __init__(self, request: Request, candidates: Iterable[Circuit]) -> None: def __init__(self, request: Request, candidates: Iterable[Circuit]) -> None:
cv_trait = CircuitValueTrait(request.device_kind, request.target_value) cv_trait = CircuitValueTrait(request.device_kind, request.target_value)
self.__device_kind = request.device_kind
self.__sorted_items = list( self.__sorted_items = list(
ResponseItem(item, cv_trait) for item in candidates ResponseItem(item, cv_trait) for item in candidates
) )
@@ -150,6 +153,10 @@ class Response:
# Cut item by limit # Cut item by limit
self.__sorted_items = self.__sorted_items[: request.count_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: def __getitem__(self, index: int) -> ResponseItem:
return self.__sorted_items[index] return self.__sorted_items[index]

View File

@@ -43,17 +43,18 @@ class LutResolver(Resolver):
"""The lookup table for inductors.""" """The lookup table for inductors."""
def __init__(self, datasets: DatasetCollection): def __init__(self, datasets: DatasetCollection):
self.__resistor_lut = self.__build_lut( self.__resistor_lut = LutResolver.__build_lut(
datasets.resistor_values, DeviceKind.RESISTOR datasets.resistor_values, DeviceKind.RESISTOR
) )
self.__capacitor_lut = self.__build_lut( self.__capacitor_lut = LutResolver.__build_lut(
datasets.capacitor_values, DeviceKind.CAPACITOR datasets.capacitor_values, DeviceKind.CAPACITOR
) )
self.__inductor_lut = self.__build_lut( self.__inductor_lut = LutResolver.__build_lut(
datasets.inductor_values, DeviceKind.INDUCTOR 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 = [ lut = [
LutItem(circuit, device_kind) LutItem(circuit, device_kind)
for circuit in chain( for circuit in chain(