feat: support save feature for dataset
This commit is contained in:
@@ -26,7 +26,7 @@ class AppResolver(enum.StrEnum):
|
|||||||
"""The BFS resolver."""
|
"""The BFS resolver."""
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class AppConfig:
|
class AppConfig:
|
||||||
"""
|
"""
|
||||||
The configuration for the app.
|
The configuration for the app.
|
||||||
|
|||||||
@@ -1,9 +1,26 @@
|
|||||||
import enum
|
import enum
|
||||||
from typing import Iterable
|
from dataclasses import dataclass
|
||||||
|
from typing import Iterable, Iterator
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from .common import LcrConnException
|
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:
|
class Dataset:
|
||||||
"""
|
"""
|
||||||
A list holding available standard values for resistor, capacitor or inductor.
|
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.
|
This list will only contain 100 and 4.7k.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__values: tuple[float, ...]
|
__values: tuple[DatasetItem, ...]
|
||||||
"""A list of available device gauge values"""
|
"""A list of available device gauge values"""
|
||||||
|
|
||||||
def __init__(self, values: tuple[float, ...]):
|
def __init__(self, str_values: Iterable[str]):
|
||||||
# Check redundant parts
|
# Check string form value one by one
|
||||||
valueset = set(values)
|
value_items: list[DatasetItem] = []
|
||||||
if len(valueset) != len(values):
|
value_set: set[float] = set()
|
||||||
raise LcrConnException(f"Duplicate item in standard value list")
|
for str_value in str_values:
|
||||||
if len(valueset) == 0:
|
# 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")
|
raise LcrConnException(f"Empty standard value list is not allowed")
|
||||||
# Ok, assign it
|
# Ok, assign it
|
||||||
self.__values = values
|
self.__values = tuple(value_items)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_iterable(stringfied_values: Iterable[str]) -> "Dataset":
|
def from_iterable(stringfied_values: Iterable[str]) -> "Dataset":
|
||||||
return Dataset(
|
return Dataset(stringfied_values)
|
||||||
tuple(
|
|
||||||
from_human_readable_value(stringfied_value)
|
|
||||||
for stringfied_value in stringfied_values
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_text(text: str) -> "Dataset":
|
def from_text(text: str) -> "Dataset":
|
||||||
@@ -48,14 +72,27 @@ class Dataset:
|
|||||||
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 Dataset.from_iterable(legal_lines)
|
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
|
@property
|
||||||
def values(self) -> tuple[float, ...]:
|
def values(self) -> Iterator[float]:
|
||||||
"""
|
"""
|
||||||
Get the available standard values
|
Get the available standard values
|
||||||
|
|
||||||
:return: A tuple of available standard values
|
:return: A tuple of available standard values
|
||||||
"""
|
"""
|
||||||
return self.__values
|
return map(lambda i: i.value, self.__values)
|
||||||
|
|
||||||
|
|
||||||
class DatasetCollection:
|
class DatasetCollection:
|
||||||
@@ -79,6 +116,14 @@ class DatasetCollection:
|
|||||||
def from_iterable(
|
def from_iterable(
|
||||||
resistor: Iterable[str], capacitor: Iterable[str], inductor: Iterable[str]
|
resistor: Iterable[str], capacitor: Iterable[str], inductor: Iterable[str]
|
||||||
) -> "DatasetCollection":
|
) -> "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(
|
return DatasetCollection(
|
||||||
Dataset.from_iterable(resistor),
|
Dataset.from_iterable(resistor),
|
||||||
Dataset.from_iterable(capacitor),
|
Dataset.from_iterable(capacitor),
|
||||||
@@ -87,6 +132,14 @@ class DatasetCollection:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_text(resistor: str, capacitor: str, inductor: str) -> "DatasetCollection":
|
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(
|
return DatasetCollection(
|
||||||
Dataset.from_text(resistor),
|
Dataset.from_text(resistor),
|
||||||
Dataset.from_text(capacitor),
|
Dataset.from_text(capacitor),
|
||||||
@@ -97,12 +150,56 @@ class DatasetCollection:
|
|||||||
def from_file(
|
def from_file(
|
||||||
resistor: Path, capacitor: Path, inductor: Path
|
resistor: Path, capacitor: Path, inductor: Path
|
||||||
) -> "DatasetCollection":
|
) -> "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(
|
return DatasetCollection(
|
||||||
Dataset.from_file(resistor),
|
Dataset.from_file(resistor),
|
||||||
Dataset.from_file(capacitor),
|
Dataset.from_file(capacitor),
|
||||||
Dataset.from_file(inductor),
|
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
|
@property
|
||||||
def resistor_values(self) -> Dataset:
|
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."""
|
"""The maximum count for the response item count passed in request."""
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Request:
|
class Request:
|
||||||
"""
|
"""
|
||||||
All request infomation for the resolver.
|
All request infomation for the resolver.
|
||||||
|
|||||||
Reference in New Issue
Block a user