feat: support save feature for dataset
This commit is contained in:
@@ -26,7 +26,7 @@ class AppResolver(enum.StrEnum):
|
||||
"""The BFS resolver."""
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True)
|
||||
class AppConfig:
|
||||
"""
|
||||
The configuration for the app.
|
||||
|
||||
@@ -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:
|
||||
"""
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user