feat: still update basic concepts
This commit is contained in:
275
legacy/common.py
275
legacy/common.py
@@ -1,14 +1,15 @@
|
|||||||
import enum
|
import enum
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
class LcrConnException(Exception):
|
class LcrConnException(Exception):
|
||||||
"""The exception thrown by LCR Connector"""
|
"""The exception thrown by LCR Connector"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DeviceKind(enum.IntEnum):
|
class DeviceKind(enum.IntEnum):
|
||||||
"""The kind of device"""
|
"""The kind of device"""
|
||||||
|
|
||||||
RESISTOR = enum.auto()
|
RESISTOR = enum.auto()
|
||||||
"""Resistor device"""
|
"""Resistor device"""
|
||||||
CAPACITOR = enum.auto()
|
CAPACITOR = enum.auto()
|
||||||
@@ -19,16 +20,16 @@ class DeviceKind(enum.IntEnum):
|
|||||||
|
|
||||||
class JointKind(enum.IntEnum):
|
class JointKind(enum.IntEnum):
|
||||||
"""The joint type between 2 devices"""
|
"""The joint type between 2 devices"""
|
||||||
|
|
||||||
SERIES = enum.auto()
|
SERIES = enum.auto()
|
||||||
"""Series connection"""
|
"""Series connection"""
|
||||||
PARALLEL = enum.auto()
|
PARALLEL = enum.auto()
|
||||||
"""Parallel connection"""
|
"""Parallel connection"""
|
||||||
|
|
||||||
def flip(self) -> 'JointKind':
|
def flip(self) -> "JointKind":
|
||||||
"""
|
"""
|
||||||
Flip the joint kind
|
Flip the joint kind
|
||||||
|
|
||||||
Flip the joint kind from series to parallel or vice versa
|
Flip the joint kind from series to parallel or vice versa
|
||||||
|
|
||||||
:return: The flipped joint kind
|
:return: The flipped joint kind
|
||||||
@@ -40,16 +41,19 @@ class JointKind(enum.IntEnum):
|
|||||||
return JointKind.SERIES
|
return JointKind.SERIES
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
class SubCircuit:
|
||||||
class CircuitJoint:
|
|
||||||
"""The part of circuit composed of two devices and the joint kind"""
|
"""The part of circuit composed of two devices and the joint kind"""
|
||||||
|
|
||||||
device_value: float
|
__device_value: float
|
||||||
"""The value of the device"""
|
"""The value of the device"""
|
||||||
joint_kind: JointKind
|
__joint_kind: JointKind
|
||||||
"""The joint kind between this device and the next device"""
|
"""The joint kind between this device and the next device"""
|
||||||
|
|
||||||
def compute(self, value: float, device_kind: DeviceKind) -> float:
|
def __init__(self, device_value: float, joint_kind: JointKind):
|
||||||
|
self.__device_value = device_value
|
||||||
|
self.__joint_kind = joint_kind
|
||||||
|
|
||||||
|
def compute(self, value: float, device_kind: DeviceKind) -> float:
|
||||||
"""
|
"""
|
||||||
Compute the joint value
|
Compute the joint value
|
||||||
|
|
||||||
@@ -57,39 +61,175 @@ class CircuitJoint:
|
|||||||
:param device_kind: The kind of the device
|
:param device_kind: The kind of the device
|
||||||
:return: The joint value computed
|
:return: The joint value computed
|
||||||
"""
|
"""
|
||||||
if self.device_value <= 0 or value <= 0:
|
if self.__device_value <= 0 or value <= 0:
|
||||||
raise LcrConnException("Device value must be greater than 0")
|
raise LcrConnException("Device value must be greater than 0")
|
||||||
|
|
||||||
# We perform series connect for: series resistor, series inductor and parallel capacitor.
|
# We perform series connect for: series resistor, series inductor and parallel capacitor.
|
||||||
# We perform parallel connect for: parallel resistor, parallel inductor and series capacitor.
|
# We perform parallel connect for: parallel resistor, parallel inductor and series capacitor.
|
||||||
joint_kind = self.joint_kind
|
joint_kind = self.__joint_kind
|
||||||
if device_kind == DeviceKind.CAPACITOR:
|
if device_kind == DeviceKind.CAPACITOR:
|
||||||
joint_kind = joint_kind.flip()
|
joint_kind = joint_kind.flip()
|
||||||
|
|
||||||
match joint_kind:
|
match joint_kind:
|
||||||
case JointKind.SERIES:
|
case JointKind.SERIES:
|
||||||
return self.device_value + value
|
return self.__device_value + value
|
||||||
case JointKind.PARALLEL:
|
case JointKind.PARALLEL:
|
||||||
return (self.device_value * value) / (self.device_value + value)
|
return (self.__device_value * value) / (self.__device_value + value)
|
||||||
|
|
||||||
|
def get_device_value(self) -> float:
|
||||||
|
"""
|
||||||
|
Get the device value
|
||||||
|
|
||||||
|
:return: The device value
|
||||||
|
"""
|
||||||
|
return self.__device_value
|
||||||
|
|
||||||
|
def get_joint_kind(self) -> JointKind:
|
||||||
|
"""
|
||||||
|
Get the joint kind
|
||||||
|
|
||||||
|
:return: The joint kind
|
||||||
|
"""
|
||||||
|
return self.__joint_kind
|
||||||
|
|
||||||
|
|
||||||
|
class CircuitDeviceCount(enum.IntEnum):
|
||||||
|
"""The number of devices in the circuit"""
|
||||||
|
|
||||||
|
ONE = enum.auto()
|
||||||
|
"""One device"""
|
||||||
|
TWO = enum.auto()
|
||||||
|
"""Two devices"""
|
||||||
|
THREE = enum.auto()
|
||||||
|
"""Three devices"""
|
||||||
|
|
||||||
|
def to_device_count(self) -> int:
|
||||||
|
match self:
|
||||||
|
case CircuitDeviceCount.ONE:
|
||||||
|
return 1
|
||||||
|
case CircuitDeviceCount.TWO:
|
||||||
|
return 2
|
||||||
|
case CircuitDeviceCount.THREE:
|
||||||
|
return 3
|
||||||
|
|
||||||
|
|
||||||
class Circuit:
|
class Circuit:
|
||||||
"""The circuit composed of multiple joints"""
|
"""The circuit composed of multiple joints"""
|
||||||
|
|
||||||
device_value: float
|
__first_device_value: float
|
||||||
"""The value of the first device"""
|
"""The value of the first device"""
|
||||||
joints: list[CircuitJoint]
|
__second_device_subckt: SubCircuit | None
|
||||||
"""The joints between devices"""
|
"""The second device and its joint property"""
|
||||||
|
__third_device_subckt: SubCircuit | None
|
||||||
|
"""The third device and its joint property"""
|
||||||
|
|
||||||
def __init__(self, value: float):
|
def __init__(
|
||||||
self.device_value = value
|
self,
|
||||||
self.joints = []
|
first_device_value: float,
|
||||||
|
second_device_subckt: SubCircuit | None,
|
||||||
|
third_device_subckt: SubCircuit | None,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Initialize the circuit
|
||||||
|
|
||||||
def add_joint(self, joint: CircuitJoint):
|
:param first_device_value: The value of the first device
|
||||||
self.joints.append(joint)
|
:param second_device_subckt: The second device and its joint property
|
||||||
|
:param third_device_subckt: The third device and its joint property
|
||||||
|
"""
|
||||||
|
if second_device_subckt is None and third_device_subckt is not None:
|
||||||
|
raise LcrConnException("Third device cannot exist without second device")
|
||||||
|
|
||||||
def len_devices(self) -> int:
|
self.__first_device_value = first_device_value
|
||||||
return len(self.joints) + 1
|
self.__second_device_subckt = second_device_subckt
|
||||||
|
self.__third_device_subckt = third_device_subckt
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_one_device(device1_value: float) -> "Circuit":
|
||||||
|
return Circuit(device1_value, None, None)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_two_devices(
|
||||||
|
device1_value: float, device2_value: float, device2_joint: JointKind
|
||||||
|
) -> "Circuit":
|
||||||
|
return Circuit(device1_value, SubCircuit(device2_value, device2_joint), None)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_three_devices(
|
||||||
|
device1_value: float,
|
||||||
|
device2_value: float,
|
||||||
|
device2_joint: JointKind,
|
||||||
|
device3_value: float,
|
||||||
|
device3_joint: JointKind,
|
||||||
|
) -> "Circuit":
|
||||||
|
return Circuit(
|
||||||
|
device1_value,
|
||||||
|
SubCircuit(device2_value, device2_joint),
|
||||||
|
SubCircuit(device3_value, device3_joint),
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_device_count(self) -> CircuitDeviceCount:
|
||||||
|
if self.__third_device_subckt is not None:
|
||||||
|
return CircuitDeviceCount.THREE
|
||||||
|
elif self.__second_device_subckt is not None:
|
||||||
|
return CircuitDeviceCount.TWO
|
||||||
|
else:
|
||||||
|
return CircuitDeviceCount.ONE
|
||||||
|
|
||||||
|
def get_first_device_value(self) -> float:
|
||||||
|
"""
|
||||||
|
Get the value of the first device
|
||||||
|
|
||||||
|
:return: The value of the first device
|
||||||
|
"""
|
||||||
|
return self.__first_device_value
|
||||||
|
|
||||||
|
def get_second_device_joint(self) -> JointKind:
|
||||||
|
"""
|
||||||
|
Get the joint kind of the second device
|
||||||
|
|
||||||
|
:return: The joint kind of the second device
|
||||||
|
:raises LcrConnException: If there is no second device
|
||||||
|
"""
|
||||||
|
if self.__second_device_subckt is not None:
|
||||||
|
return self.__second_device_subckt.get_joint_kind()
|
||||||
|
else:
|
||||||
|
raise LcrConnException("No second device")
|
||||||
|
|
||||||
|
def get_second_device_value(self) -> float:
|
||||||
|
"""
|
||||||
|
Get the value of the second device
|
||||||
|
|
||||||
|
:return: The value of the second device
|
||||||
|
:raises LcrConnException: If there is no second device
|
||||||
|
"""
|
||||||
|
if self.__second_device_subckt is not None:
|
||||||
|
return self.__second_device_subckt.get_device_value()
|
||||||
|
else:
|
||||||
|
raise LcrConnException("No second device")
|
||||||
|
|
||||||
|
def get_third_device_joint(self) -> JointKind:
|
||||||
|
"""
|
||||||
|
Get the joint kind of the third device
|
||||||
|
|
||||||
|
:return: The joint kind of the third device
|
||||||
|
:raises LcrConnException: If there is no third device
|
||||||
|
"""
|
||||||
|
if self.__third_device_subckt is not None:
|
||||||
|
return self.__third_device_subckt.get_joint_kind()
|
||||||
|
else:
|
||||||
|
raise LcrConnException("No third device")
|
||||||
|
|
||||||
|
def get_third_device_value(self) -> float:
|
||||||
|
"""
|
||||||
|
Get the value of the third device
|
||||||
|
|
||||||
|
:return: The value of the third device
|
||||||
|
:raises LcrConnException: If there is no third device
|
||||||
|
"""
|
||||||
|
if self.__third_device_subckt is not None:
|
||||||
|
return self.__third_device_subckt.get_device_value()
|
||||||
|
else:
|
||||||
|
raise LcrConnException("No third device")
|
||||||
|
|
||||||
def compute(self, device_kind: DeviceKind) -> float:
|
def compute(self, device_kind: DeviceKind) -> float:
|
||||||
"""
|
"""
|
||||||
@@ -98,77 +238,14 @@ class Circuit:
|
|||||||
:param device_kind: The kind of the device
|
:param device_kind: The kind of the device
|
||||||
:return: The circuit value
|
:return: The circuit value
|
||||||
"""
|
"""
|
||||||
if self.device_value <= 0:
|
if self.__first_device_value <= 0:
|
||||||
raise LcrConnException("Device value must be greater than 0")
|
raise LcrConnException("Device value must be greater than 0")
|
||||||
|
|
||||||
value = self.device_value
|
value = self.__first_device_value
|
||||||
for joint in self.joints:
|
if self.__second_device_subckt is None:
|
||||||
value = joint.compute(value, device_kind)
|
return value
|
||||||
|
value = self.__second_device_subckt.compute(value, device_kind)
|
||||||
|
if self.__third_device_subckt is None:
|
||||||
|
return value
|
||||||
|
value = self.__third_device_subckt.compute(value, device_kind)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def from_human_readable_value(strl: str) -> float:
|
|
||||||
"""
|
|
||||||
Convert human readable value to float
|
|
||||||
|
|
||||||
:param strl: The human readable value
|
|
||||||
:return: The parsed float value
|
|
||||||
:raises ValueError: If the input string is not a valid number
|
|
||||||
"""
|
|
||||||
strl = strl.strip()
|
|
||||||
|
|
||||||
if strl.endswith('n'):
|
|
||||||
return float(strl[0:-1]) * 1e-12
|
|
||||||
if strl.endswith('p'):
|
|
||||||
return float(strl[0:-1]) * 1e-9
|
|
||||||
if strl.endswith('u'):
|
|
||||||
return float(strl[0:-1]) * 1e-6
|
|
||||||
if strl.endswith('m'):
|
|
||||||
return float(strl[0:-1]) * 1e-3
|
|
||||||
if strl.endswith('k'):
|
|
||||||
return float(strl[0:-1]) * 1e3
|
|
||||||
if strl.endswith('M'):
|
|
||||||
return float(strl[0:-1]) * 1e6
|
|
||||||
if strl.endswith('G'):
|
|
||||||
return float(strl[0:-1]) * 1e9
|
|
||||||
return float(strl)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def to_human_readable_value(v: float) -> str:
|
|
||||||
"""
|
|
||||||
Convert float value to human readable value
|
|
||||||
|
|
||||||
:param value: The float value
|
|
||||||
:return: The human readable value
|
|
||||||
"""
|
|
||||||
if v / 1e-12 < 1e3:
|
|
||||||
return "{:e} n".format(v / 1e-12)
|
|
||||||
if v / 1e-9 < 1e3:
|
|
||||||
return "{:.4f} p".format(v / 1e-9)
|
|
||||||
if v / 1e-6 < 1e3:
|
|
||||||
return "{:.4f} u".format(v / 1e-6)
|
|
||||||
if v / 1e-3 < 1e3:
|
|
||||||
return "{:.4f} m".format(v / 1e-3)
|
|
||||||
if v < 1e3:
|
|
||||||
return "{:.4f}".format(v)
|
|
||||||
if v / 1e3 < 1e3:
|
|
||||||
return "{:.4f} k".format(v / 1e3)
|
|
||||||
if v / 1e6 < 1e3:
|
|
||||||
return "{:.4f} M".format(v / 1e6)
|
|
||||||
if v / 1e9 < 1e3:
|
|
||||||
return "{:.4f} G".format(v / 1e9)
|
|
||||||
|
|
||||||
return "{:e}".format(v)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,61 +1,178 @@
|
|||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from dataclasses import dataclass
|
from .common import LcrConnException
|
||||||
from .common import LcrConnException, from_human_readable_value
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
class Dataset:
|
||||||
class DataSubset:
|
"""
|
||||||
"""A list holding available device gauge values for resistor, capacitor or inductor"""
|
A list holding available standard values for resistor, capacitor or inductor.
|
||||||
|
|
||||||
gauges: tuple[float, ...]
|
Standard values is a collection of all possible values of specific device manufactured by electronic factory.
|
||||||
|
In reality, it also can be replaced by all possible values of specific device provided by your laboratory.
|
||||||
|
For example, your laboratory only provide resistor with 100 Ohm and 4.7k Ohm.
|
||||||
|
This list will only contain 100 and 4.7k.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__values: tuple[float, ...]
|
||||||
"""A list of available device gauge values"""
|
"""A list of available device gauge values"""
|
||||||
|
|
||||||
@staticmethod
|
def __init__(self, values: tuple[float, ...]):
|
||||||
def from_iterable(str_gauges: Iterable[str]) -> "DataSubset":
|
# Check redundant parts
|
||||||
# Remove redundant parts
|
valueset = set(values)
|
||||||
gauges_set: set[float] = set()
|
if len(valueset) != len(values):
|
||||||
for str_gauge in str_gauges:
|
raise LcrConnException(f"Duplicate standard value")
|
||||||
numeric_gauge = from_human_readable_value(str_gauge)
|
# Ok, assign it
|
||||||
if numeric_gauge in gauges_set:
|
self.__values = values
|
||||||
raise LcrConnException(f"Duplicate gauge value found: {str_gauge}")
|
|
||||||
else:
|
|
||||||
gauges_set.add(numeric_gauge)
|
|
||||||
# Return value
|
|
||||||
return DataSubset(tuple(gauges_set))
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_file(filename: Path) -> "DataSubset":
|
def from_iterable(stringfied_values: Iterable[str]) -> "Dataset":
|
||||||
|
return Dataset(
|
||||||
|
tuple(
|
||||||
|
from_human_readable_value(stringfied_value)
|
||||||
|
for stringfied_value in stringfied_values
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_text(text: str) -> "Dataset":
|
||||||
|
lines = text.split("\n")
|
||||||
|
legal_lines = filter(lambda line: line != "", (line.strip() for line in lines))
|
||||||
|
return Dataset.from_iterable(legal_lines)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_file(filename: Path) -> "Dataset":
|
||||||
with open(filename, "r", encoding="utf-8") as f:
|
with open(filename, "r", encoding="utf-8") as f:
|
||||||
legal_lines = filter(lambda line: line != "", (line.strip() for line in f))
|
legal_lines = filter(lambda line: line != "", (line.strip() for line in f))
|
||||||
return DataSubset.from_iterable(legal_lines)
|
return Dataset.from_iterable(legal_lines)
|
||||||
|
|
||||||
|
def get_values(self) -> tuple[float, ...]:
|
||||||
|
"""
|
||||||
|
Get the available standard values
|
||||||
|
|
||||||
|
:return: A tuple of available standard values
|
||||||
|
"""
|
||||||
|
return self.__values
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
class DatasetCollection:
|
||||||
class DataSet:
|
"""
|
||||||
"""The dataset include 3 lists of available device gauge values for resistor, capacitor and inductor"""
|
The collection holding all standard values for resistor, capacitor and inductor respectively.
|
||||||
|
"""
|
||||||
|
|
||||||
resistor: DataSubset
|
__resistor: Dataset
|
||||||
"""A list of available device gauge values for resistor"""
|
"""A list of available device gauge values for resistor"""
|
||||||
capacitor: DataSubset
|
__capacitor: Dataset
|
||||||
"""A list of available device gauge values for capacitor"""
|
"""A list of available device gauge values for capacitor"""
|
||||||
inductor: DataSubset
|
__inductor: Dataset
|
||||||
"""A list of available device gauge values for inductor"""
|
"""A list of available device gauge values for inductor"""
|
||||||
|
|
||||||
|
def __init__(self, resistor: Dataset, capacitor: Dataset, inductor: Dataset):
|
||||||
|
self.__resistor = resistor
|
||||||
|
self.__capacitor = capacitor
|
||||||
|
self.__inductor = inductor
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_iterable(
|
def from_iterable(
|
||||||
resistor: Iterable[str], capacitor: Iterable[str], inductor: Iterable[str]
|
resistor: Iterable[str], capacitor: Iterable[str], inductor: Iterable[str]
|
||||||
) -> "DataSet":
|
) -> "DatasetCollection":
|
||||||
return DataSet(
|
return DatasetCollection(
|
||||||
DataSubset.from_iterable(resistor),
|
Dataset.from_iterable(resistor),
|
||||||
DataSubset.from_iterable(capacitor),
|
Dataset.from_iterable(capacitor),
|
||||||
DataSubset.from_iterable(inductor),
|
Dataset.from_iterable(inductor),
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_file(resistor: Path, capacitor: Path, inductor: Path) -> "DataSet":
|
def from_text(resistor: str, capacitor: str, inductor: str) -> "DatasetCollection":
|
||||||
return DataSet(
|
return DatasetCollection(
|
||||||
DataSubset.from_file(resistor),
|
Dataset.from_text(resistor),
|
||||||
DataSubset.from_file(capacitor),
|
Dataset.from_text(capacitor),
|
||||||
DataSubset.from_file(inductor),
|
Dataset.from_text(inductor),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_file(
|
||||||
|
resistor: Path, capacitor: Path, inductor: Path
|
||||||
|
) -> "DatasetCollection":
|
||||||
|
return DatasetCollection(
|
||||||
|
Dataset.from_file(resistor),
|
||||||
|
Dataset.from_file(capacitor),
|
||||||
|
Dataset.from_file(inductor),
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_resistor_values(self) -> tuple[float, ...]:
|
||||||
|
"""
|
||||||
|
Get the available standard values for resistor
|
||||||
|
|
||||||
|
:return: A tuple of available standard values for resistor
|
||||||
|
"""
|
||||||
|
return self.__resistor.get_values()
|
||||||
|
|
||||||
|
def get_capacitor_values(self) -> tuple[float, ...]:
|
||||||
|
"""
|
||||||
|
Get the available standard values for capacitor
|
||||||
|
|
||||||
|
:return: A tuple of available standard values for capacitor
|
||||||
|
"""
|
||||||
|
return self.__capacitor.get_values()
|
||||||
|
|
||||||
|
def get_inductor_values(self) -> tuple[float, ...]:
|
||||||
|
"""
|
||||||
|
Get the available standard values for inductor
|
||||||
|
|
||||||
|
:return: A tuple of available standard values for inductor
|
||||||
|
"""
|
||||||
|
return self.__inductor.get_values()
|
||||||
|
|
||||||
|
|
||||||
|
def from_human_readable_value(strl: str) -> float:
|
||||||
|
"""
|
||||||
|
Convert human readable value to float
|
||||||
|
|
||||||
|
:param strl: The human readable value
|
||||||
|
:return: The parsed float value
|
||||||
|
:raises ValueError: If the input string is not a valid number
|
||||||
|
"""
|
||||||
|
strl = strl.strip()
|
||||||
|
|
||||||
|
if strl.endswith("n"):
|
||||||
|
return float(strl[0:-1]) * 1e-12
|
||||||
|
if strl.endswith("p"):
|
||||||
|
return float(strl[0:-1]) * 1e-9
|
||||||
|
if strl.endswith("u"):
|
||||||
|
return float(strl[0:-1]) * 1e-6
|
||||||
|
if strl.endswith("m"):
|
||||||
|
return float(strl[0:-1]) * 1e-3
|
||||||
|
if strl.endswith("k"):
|
||||||
|
return float(strl[0:-1]) * 1e3
|
||||||
|
if strl.endswith("M"):
|
||||||
|
return float(strl[0:-1]) * 1e6
|
||||||
|
if strl.endswith("G"):
|
||||||
|
return float(strl[0:-1]) * 1e9
|
||||||
|
return float(strl)
|
||||||
|
|
||||||
|
|
||||||
|
def to_human_readable_value(v: float) -> str:
|
||||||
|
"""
|
||||||
|
Convert float value to human readable value
|
||||||
|
|
||||||
|
:param value: The float value
|
||||||
|
:return: The human readable value
|
||||||
|
"""
|
||||||
|
if v / 1e-12 < 1e3:
|
||||||
|
return "{:e} n".format(v / 1e-12)
|
||||||
|
if v / 1e-9 < 1e3:
|
||||||
|
return "{:.4f} p".format(v / 1e-9)
|
||||||
|
if v / 1e-6 < 1e3:
|
||||||
|
return "{:.4f} u".format(v / 1e-6)
|
||||||
|
if v / 1e-3 < 1e3:
|
||||||
|
return "{:.4f} m".format(v / 1e-3)
|
||||||
|
if v < 1e3:
|
||||||
|
return "{:.4f}".format(v)
|
||||||
|
if v / 1e3 < 1e3:
|
||||||
|
return "{:.4f} k".format(v / 1e3)
|
||||||
|
if v / 1e6 < 1e3:
|
||||||
|
return "{:.4f} M".format(v / 1e6)
|
||||||
|
if v / 1e9 < 1e3:
|
||||||
|
return "{:.4f} G".format(v / 1e9)
|
||||||
|
|
||||||
|
return "{:e}".format(v)
|
||||||
|
|||||||
@@ -12,23 +12,23 @@ def _get_joint_kind_symbol(joint_kind: JointKind) -> str:
|
|||||||
def _illustrate_circuit(circuit: Circuit) -> None:
|
def _illustrate_circuit(circuit: Circuit) -> None:
|
||||||
match circuit.len_devices():
|
match circuit.len_devices():
|
||||||
case 1:
|
case 1:
|
||||||
dev1 = to_human_readable_value(circuit.device_value)
|
dev1 = to_human_readable_value(circuit.__first_device_value)
|
||||||
print(f"{dev1}")
|
print(f"{dev1}")
|
||||||
case 2:
|
case 2:
|
||||||
dev1 = to_human_readable_value(circuit.device_value)
|
dev1 = to_human_readable_value(circuit.__first_device_value)
|
||||||
joint1 = circuit.joints[0]
|
joint1 = circuit.joints[0]
|
||||||
j1 = _get_joint_kind_symbol(joint1.joint_kind)
|
j1 = _get_joint_kind_symbol(joint1.__joint_kind)
|
||||||
dev2 = to_human_readable_value(joint1.device_value)
|
dev2 = to_human_readable_value(joint1.__device_value)
|
||||||
print(f"[{j1}] ┬ {dev1}")
|
print(f"[{j1}] ┬ {dev1}")
|
||||||
print(f" └ {dev2}")
|
print(f" └ {dev2}")
|
||||||
case 3:
|
case 3:
|
||||||
dev1 = to_human_readable_value(circuit.device_value)
|
dev1 = to_human_readable_value(circuit.__first_device_value)
|
||||||
joint1 = circuit.joints[0]
|
joint1 = circuit.joints[0]
|
||||||
j1 = _get_joint_kind_symbol(joint1.joint_kind)
|
j1 = _get_joint_kind_symbol(joint1.__joint_kind)
|
||||||
dev2 = to_human_readable_value(joint1.device_value)
|
dev2 = to_human_readable_value(joint1.__device_value)
|
||||||
joint2 = circuit.joints[1]
|
joint2 = circuit.joints[1]
|
||||||
j2 = _get_joint_kind_symbol(joint2.joint_kind)
|
j2 = _get_joint_kind_symbol(joint2.__joint_kind)
|
||||||
dev3 = to_human_readable_value(joint2.device_value)
|
dev3 = to_human_readable_value(joint2.__device_value)
|
||||||
print(f"[{j2}] ┬ [{j1}] ┬ {dev1}")
|
print(f"[{j2}] ┬ [{j1}] ┬ {dev1}")
|
||||||
print(f" │ └ {dev2}")
|
print(f" │ └ {dev2}")
|
||||||
print(f" └ {dev3}")
|
print(f" └ {dev3}")
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
from typing import Iterator
|
from typing import Iterator
|
||||||
from .common import Resolver, ResolverRequest, ResolverResult, ResultPriority
|
from .common import Resolver, ResolverRequest, ResolverResult, ResultPriority
|
||||||
from ..dataset import DataSet
|
from ..dataset import DatasetCollection
|
||||||
|
|
||||||
class AStarResolver(Resolver):
|
class AStarResolver(Resolver):
|
||||||
"""
|
"""
|
||||||
A resolver that uses A* algorithm to find the best matching circuit.
|
A resolver that uses A* algorithm to find the best matching circuit.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, dataset: DataSet):
|
def __init__(self, dataset: DatasetCollection):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import struct
|
|||||||
from typing import Iterator, BinaryIO
|
from typing import Iterator, BinaryIO
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from .common import Resolver, ResolverRequest, ResolverResult, ResultPriority
|
from .common import Resolver, ResolverRequest, ResolverResult, ResultPriority
|
||||||
from ..dataset import DataSet
|
from ..dataset import DatasetCollection
|
||||||
from ..common import Circuit, CircuitJoint, JointKind, LcrConnException
|
from ..common import Circuit, SubCircuit, JointKind, LcrConnException
|
||||||
|
|
||||||
class LutResolver(Resolver):
|
class LutResolver(Resolver):
|
||||||
"""
|
"""
|
||||||
@@ -16,7 +16,7 @@ class LutResolver(Resolver):
|
|||||||
self.lut = lut
|
self.lut = lut
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_dataset(dataset: DataSet) -> 'LutResolver':
|
def from_dataset(dataset: DatasetCollection) -> 'LutResolver':
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -61,14 +61,14 @@ class LutItem:
|
|||||||
for _ in range(cnt):
|
for _ in range(cnt):
|
||||||
j = JointKind.SERIES if _read_bool(f) else JointKind.PARALLEL
|
j = JointKind.SERIES if _read_bool(f) else JointKind.PARALLEL
|
||||||
dev = _read_double(f)
|
dev = _read_double(f)
|
||||||
joint = CircuitJoint(j, dev)
|
joint = SubCircuit(j, dev)
|
||||||
circuit.add_joint(joint)
|
circuit.add_joint(joint)
|
||||||
|
|
||||||
return LutItem(circuit)
|
return LutItem(circuit)
|
||||||
|
|
||||||
def save_as_cache(self, f: BinaryIO) -> None:
|
def save_as_cache(self, f: BinaryIO) -> None:
|
||||||
_write_int(f, self.circuit.len_devices())
|
_write_int(f, self.circuit.len_devices())
|
||||||
_write_double(f, self.circuit.device_value)
|
_write_double(f, self.circuit.__first_device_value)
|
||||||
for joint in self.circuit.joints():
|
for joint in self.circuit.joints():
|
||||||
_write_bool(f, joint.kind == JointKind.SERIES)
|
_write_bool(f, joint.kind == JointKind.SERIES)
|
||||||
_write_double(f, joint.value)
|
_write_double(f, joint.value)
|
||||||
|
|||||||
Reference in New Issue
Block a user