1
0
Files
LCRConnector/legacy/src/lcr_connector/dataset.py

185 lines
5.6 KiB
Python
Raw Normal View History

2026-06-02 21:08:48 +08:00
from typing import Iterable
from pathlib import Path
from .common import LcrConnException
2026-06-02 21:08:48 +08:00
2026-06-15 13:47:31 +08:00
class Dataset:
"""
A list holding available standard values for resistor, capacitor or inductor.
2026-06-02 21:08:48 +08:00
2026-06-15 13:47:31 +08:00
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, ...]
2026-06-02 21:08:48 +08:00
"""A list of available device gauge values"""
2026-06-15 13:47:31 +08:00
def __init__(self, values: tuple[float, ...]):
# Check redundant parts
valueset = set(values)
if len(valueset) != len(values):
2026-06-15 15:58:04 +08:00
raise LcrConnException(f"Duplicate item in standard value list")
if len(valueset) == 0:
raise LcrConnException(f"Empty standard value list is not allowed")
2026-06-15 13:47:31 +08:00
# Ok, assign it
self.__values = values
2026-06-02 21:08:48 +08:00
@staticmethod
2026-06-15 13:47:31 +08:00
def from_iterable(stringfied_values: Iterable[str]) -> "Dataset":
return Dataset(
tuple(
from_human_readable_value(stringfied_value)
for stringfied_value in stringfied_values
)
)
2026-06-02 21:08:48 +08:00
@staticmethod
2026-06-15 13:47:31 +08:00
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":
2026-06-02 21:08:48 +08:00
with open(filename, "r", encoding="utf-8") as f:
legal_lines = filter(lambda line: line != "", (line.strip() for line in f))
2026-06-15 13:47:31 +08:00
return Dataset.from_iterable(legal_lines)
2026-06-15 15:58:04 +08:00
@property
def values(self) -> tuple[float, ...]:
2026-06-15 13:47:31 +08:00
"""
Get the available standard values
:return: A tuple of available standard values
"""
return self.__values
2026-06-02 21:08:48 +08:00
2026-06-15 13:47:31 +08:00
class DatasetCollection:
"""
The collection holding all standard values for resistor, capacitor and inductor respectively.
"""
2026-06-02 21:08:48 +08:00
2026-06-15 13:47:31 +08:00
__resistor: Dataset
2026-06-02 21:08:48 +08:00
"""A list of available device gauge values for resistor"""
2026-06-15 13:47:31 +08:00
__capacitor: Dataset
2026-06-02 21:08:48 +08:00
"""A list of available device gauge values for capacitor"""
2026-06-15 13:47:31 +08:00
__inductor: Dataset
2026-06-02 21:08:48 +08:00
"""A list of available device gauge values for inductor"""
2026-06-15 13:47:31 +08:00
def __init__(self, resistor: Dataset, capacitor: Dataset, inductor: Dataset):
self.__resistor = resistor
self.__capacitor = capacitor
self.__inductor = inductor
2026-06-02 21:08:48 +08:00
@staticmethod
def from_iterable(
resistor: Iterable[str], capacitor: Iterable[str], inductor: Iterable[str]
2026-06-15 13:47:31 +08:00
) -> "DatasetCollection":
return DatasetCollection(
Dataset.from_iterable(resistor),
Dataset.from_iterable(capacitor),
Dataset.from_iterable(inductor),
)
@staticmethod
def from_text(resistor: str, capacitor: str, inductor: str) -> "DatasetCollection":
return DatasetCollection(
Dataset.from_text(resistor),
Dataset.from_text(capacitor),
Dataset.from_text(inductor),
2026-06-02 21:08:48 +08:00
)
@staticmethod
2026-06-15 13:47:31 +08:00
def from_file(
resistor: Path, capacitor: Path, inductor: Path
) -> "DatasetCollection":
return DatasetCollection(
Dataset.from_file(resistor),
Dataset.from_file(capacitor),
Dataset.from_file(inductor),
2026-06-02 21:08:48 +08:00
)
2026-06-15 13:47:31 +08:00
2026-06-15 15:58:04 +08:00
@property
def resistor_values(self) -> Dataset:
2026-06-15 13:47:31 +08:00
"""
Get the available standard values for resistor
:return: A tuple of available standard values for resistor
"""
2026-06-15 15:58:04 +08:00
return self.__resistor
2026-06-15 13:47:31 +08:00
2026-06-15 15:58:04 +08:00
@property
def capacitor_values(self) -> Dataset:
2026-06-15 13:47:31 +08:00
"""
Get the available standard values for capacitor
:return: A tuple of available standard values for capacitor
"""
2026-06-15 15:58:04 +08:00
return self.__capacitor
2026-06-15 13:47:31 +08:00
2026-06-15 15:58:04 +08:00
@property
def inductor_values(self) -> Dataset:
2026-06-15 13:47:31 +08:00
"""
Get the available standard values for inductor
:return: A tuple of available standard values for inductor
"""
2026-06-15 15:58:04 +08:00
return self.__inductor
2026-06-15 13:47:31 +08:00
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)