1
0

feat: support save feature for dataset

This commit is contained in:
2026-06-28 13:55:03 +08:00
parent 5ad3e11836
commit 215146bf59
3 changed files with 116 additions and 19 deletions

View File

@@ -26,7 +26,7 @@ class AppResolver(enum.StrEnum):
"""The BFS resolver."""
@dataclass
@dataclass(frozen=True)
class AppConfig:
"""
The configuration for the app.

View File

@@ -1,9 +1,26 @@
import enum
from typing import Iterable
from dataclasses import dataclass
from typing import Iterable, Iterator
from pathlib import Path
from .common import LcrConnException
@dataclass(frozen=True)
class DatasetItem:
value: float
"""The actual value of this item."""
str_value: str
"""The string form of this value given from original input for re-saving."""
def __post_init__(self):
value = self.value
if value <= 0:
raise ValueError(f"Invalid value {value} in dataset")
str_value = self.str_value
if len(str_value) == 0:
raise ValueError(f"Unexpected empty string in dataset item")
class Dataset:
"""
A list holding available standard values for resistor, capacitor or inductor.
@@ -14,27 +31,34 @@ class Dataset:
This list will only contain 100 and 4.7k.
"""
__values: tuple[float, ...]
__values: tuple[DatasetItem, ...]
"""A list of available device gauge values"""
def __init__(self, values: tuple[float, ...]):
# Check redundant parts
valueset = set(values)
if len(valueset) != len(values):
raise LcrConnException(f"Duplicate item in standard value list")
if len(valueset) == 0:
def __init__(self, str_values: Iterable[str]):
# Check string form value one by one
value_items: list[DatasetItem] = []
value_set: set[float] = set()
for str_value in str_values:
# Try parsing value
value = from_human_readable_value(str_value)
# Check and update set
if value in value_set:
raise LcrConnException(
f"Duplicate item {str_value} in standard value list"
)
else:
value_set.add(value)
# Add into result
value_items.append(DatasetItem(value, str_value))
# Check empty case
if len(value_items) == 0:
raise LcrConnException(f"Empty standard value list is not allowed")
# Ok, assign it
self.__values = values
self.__values = tuple(value_items)
@staticmethod
def from_iterable(stringfied_values: Iterable[str]) -> "Dataset":
return Dataset(
tuple(
from_human_readable_value(stringfied_value)
for stringfied_value in stringfied_values
)
)
return Dataset(stringfied_values)
@staticmethod
def from_text(text: str) -> "Dataset":
@@ -48,14 +72,27 @@ class Dataset:
legal_lines = filter(lambda line: line != "", (line.strip() for line in f))
return Dataset.from_iterable(legal_lines)
def __save(self) -> Iterator[str]:
return map(lambda i: i.str_value, self.__values)
def save_iterator(self) -> Iterator[str]:
return self.__save()
def save_text(self) -> str:
return "\n".join(self.__save())
def save_file(self, filename: Path) -> None:
with open(filename, "w", encoding="utf-8") as f:
f.write(self.save_text())
@property
def values(self) -> tuple[float, ...]:
def values(self) -> Iterator[float]:
"""
Get the available standard values
:return: A tuple of available standard values
"""
return self.__values
return map(lambda i: i.value, self.__values)
class DatasetCollection:
@@ -79,6 +116,14 @@ class DatasetCollection:
def from_iterable(
resistor: Iterable[str], capacitor: Iterable[str], inductor: Iterable[str]
) -> "DatasetCollection":
"""
Load the standard values for resistor, capacitor and inductor respectively from iterables.
:param resistor: The iterable to load available standard values for resistor
:param capacitor: The iterable to load available standard values for capacitor
:param inductor: The iterable to load available standard values for inductor
:return: The built dataset collection
"""
return DatasetCollection(
Dataset.from_iterable(resistor),
Dataset.from_iterable(capacitor),
@@ -87,6 +132,14 @@ class DatasetCollection:
@staticmethod
def from_text(resistor: str, capacitor: str, inductor: str) -> "DatasetCollection":
"""
Load the standard values for resistor, capacitor and inductor respectively from strings.
:param resistor: The string to load available standard values for resistor
:param capacitor: The string to load available standard values for capacitor
:param inductor: The string to load available standard values for inductor
:return: The built dataset collection
"""
return DatasetCollection(
Dataset.from_text(resistor),
Dataset.from_text(capacitor),
@@ -97,12 +150,56 @@ class DatasetCollection:
def from_file(
resistor: Path, capacitor: Path, inductor: Path
) -> "DatasetCollection":
"""
Load the standard values for resistor, capacitor and inductor respectively from files.
:param resistor: The file to load available standard values for resistor
:param capacitor: The file to load available standard values for capacitor
:param inductor: The file to load available standard values for inductor
:return: The built dataset collection
"""
return DatasetCollection(
Dataset.from_file(resistor),
Dataset.from_file(capacitor),
Dataset.from_file(inductor),
)
def save_iterator(self) -> tuple[Iterator[str], Iterator[str], Iterator[str]]:
"""
Get the iterator of available standard values for resistor, capacitor and inductor respectively.
:return: A tuple of iterators of available standard values for resistor, capacitor and inductor respectively.
"""
return (
self.__resistor.save_iterator(),
self.__capacitor.save_iterator(),
self.__inductor.save_iterator(),
)
def save_text(self) -> tuple[str, str, str]:
"""
Get the string form of available standard values for resistor, capacitor and inductor respectively.
:return: A tuple of strings of available standard values for resistor, capacitor and inductor respectively.
"""
return (
self.__resistor.save_text(),
self.__capacitor.save_text(),
self.__inductor.save_text(),
)
def save_file(self, resistor: Path, capacitor: Path, inductor: Path) -> None:
"""
Save the available standard values for resistor, capacitor and inductor respectively to files.
:param resistor: The file to save available standard values for resistor
:param capacitor: The file to save available standard values for capacitor
:param inductor: The file to save available standard values for inductor
"""
self.__resistor.save_file(resistor)
self.__capacitor.save_file(capacitor)
self.__inductor.save_file(inductor)
@property
def resistor_values(self) -> Dataset:
"""

View File

@@ -20,7 +20,7 @@ MAX_RESPONSE_CNT: int = 50
"""The maximum count for the response item count passed in request."""
@dataclass
@dataclass(frozen=True)
class Request:
"""
All request infomation for the resolver.