Rename Values -> ValueGroup
This commit is contained in:
parent
8306fb4c3e
commit
48444cc3ce
@ -13,7 +13,7 @@ from .tree_formatters import (
|
|||||||
node_tree_to_html,
|
node_tree_to_html,
|
||||||
node_tree_to_string,
|
node_tree_to_string,
|
||||||
)
|
)
|
||||||
from .value_types import QEnum, Values, values_from_json
|
from .value_types import QEnum, ValueGroup, values_from_json
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=False, eq=True, order=True, unsafe_hash=True)
|
@dataclass(frozen=False, eq=True, order=True, unsafe_hash=True)
|
||||||
@ -26,7 +26,7 @@ class Qube:
|
|||||||
return self.data.key
|
return self.data.key
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def values(self) -> Values:
|
def values(self) -> ValueGroup:
|
||||||
return self.data.values
|
return self.data.values
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -51,7 +51,7 @@ class Qube:
|
|||||||
return self.data.summary()
|
return self.data.summary()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def make(cls, key: str, values: Values, children, **kwargs) -> "Qube":
|
def make(cls, key: str, values: ValueGroup, children, **kwargs) -> "Qube":
|
||||||
return cls(
|
return cls(
|
||||||
data=NodeData(key, values, metadata=kwargs.get("metadata", frozendict())),
|
data=NodeData(key, values, metadata=kwargs.get("metadata", frozendict())),
|
||||||
children=tuple(sorted(children, key=lambda n: ((n.key, n.values.min())))),
|
children=tuple(sorted(children, key=lambda n: ((n.key, n.values.min())))),
|
||||||
|
@ -3,13 +3,13 @@ from typing import Hashable
|
|||||||
|
|
||||||
from frozendict import frozendict
|
from frozendict import frozendict
|
||||||
|
|
||||||
from .value_types import Values
|
from .value_types import ValueGroup
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=False, eq=True, order=True, unsafe_hash=True)
|
@dataclass(frozen=False, eq=True, order=True, unsafe_hash=True)
|
||||||
class NodeData:
|
class NodeData:
|
||||||
key: str
|
key: str
|
||||||
values: Values
|
values: ValueGroup
|
||||||
metadata: dict[str, tuple[Hashable, ...]] = field(
|
metadata: dict[str, tuple[Hashable, ...]] = field(
|
||||||
default_factory=frozendict, compare=False
|
default_factory=frozendict, compare=False
|
||||||
)
|
)
|
||||||
|
@ -8,7 +8,7 @@ from typing import TYPE_CHECKING, Iterable
|
|||||||
from frozendict import frozendict
|
from frozendict import frozendict
|
||||||
|
|
||||||
from .node_types import NodeData
|
from .node_types import NodeData
|
||||||
from .value_types import QEnum, Values
|
from .value_types import QEnum, ValueGroup
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .qube import Qube
|
from .qube import Qube
|
||||||
@ -22,8 +22,8 @@ class SetOperation(Enum):
|
|||||||
|
|
||||||
|
|
||||||
def fused_set_operations(
|
def fused_set_operations(
|
||||||
A: "Values", B: "Values"
|
A: "ValueGroup", B: "ValueGroup"
|
||||||
) -> tuple[list[Values], list[Values], list[Values]]:
|
) -> tuple[list[ValueGroup], list[ValueGroup], list[ValueGroup]]:
|
||||||
if isinstance(A, QEnum) and isinstance(B, QEnum):
|
if isinstance(A, QEnum) and isinstance(B, QEnum):
|
||||||
set_A, set_B = set(A), set(B)
|
set_A, set_B = set(A), set(B)
|
||||||
intersection = set_A & set_B
|
intersection = set_A & set_B
|
||||||
@ -46,7 +46,9 @@ def fused_set_operations(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def node_intersection(A: "Values", B: "Values") -> tuple[Values, Values, Values]:
|
def node_intersection(
|
||||||
|
A: "ValueGroup", B: "ValueGroup"
|
||||||
|
) -> tuple[ValueGroup, ValueGroup, ValueGroup]:
|
||||||
if isinstance(A, QEnum) and isinstance(B, QEnum):
|
if isinstance(A, QEnum) and isinstance(B, QEnum):
|
||||||
set_A, set_B = set(A), set(B)
|
set_A, set_B = set(A), set(B)
|
||||||
intersection = set_A & set_B
|
intersection = set_A & set_B
|
||||||
|
@ -9,33 +9,41 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Values(ABC):
|
class ValueGroup(ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def summary(self) -> str:
|
def summary(self) -> str:
|
||||||
|
"Provide a string summary of the value group."
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def __len__(self) -> int:
|
def __len__(self) -> int:
|
||||||
|
"Return how many values this group contains."
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def __contains__(self, value: Any) -> bool:
|
def __contains__(self, value: Any) -> bool:
|
||||||
|
"Given a value, coerce to the value type and determine if it is in the value group."
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def __iter__(self) -> Iterable[Any]:
|
def __iter__(self) -> Iterable[Any]:
|
||||||
|
"Iterate over the values in the group."
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def from_strings(self, values: Iterable[str]) -> list["Values"]:
|
def from_strings(cls, values: Iterable[str]) -> list["ValueGroup"]:
|
||||||
|
"Given a list of strings, return a one or more ValueGroups of this type."
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def min(self):
|
def min(self):
|
||||||
|
"Return the minimum value in the group."
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def to_json(self):
|
def to_json(self) -> dict:
|
||||||
|
"Return a JSON serializable representation of the value group."
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@ -44,7 +52,7 @@ EnumValuesType = FrozenSet[T]
|
|||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True, order=True)
|
@dataclass(frozen=True, order=True)
|
||||||
class QEnum(Values):
|
class QEnum(ValueGroup):
|
||||||
"""
|
"""
|
||||||
The simplest kind of key value is just a list of strings.
|
The simplest kind of key value is just a list of strings.
|
||||||
summary -> string1/string2/string....
|
summary -> string1/string2/string....
|
||||||
@ -70,7 +78,7 @@ class QEnum(Values):
|
|||||||
def __contains__(self, value: Any) -> bool:
|
def __contains__(self, value: Any) -> bool:
|
||||||
return value in self.values
|
return value in self.values
|
||||||
|
|
||||||
def from_strings(self, values: Iterable[str]) -> list["Values"]:
|
def from_strings(self, values: Iterable[str]) -> list["ValueGroup"]:
|
||||||
return [type(self)(tuple(values))]
|
return [type(self)(tuple(values))]
|
||||||
|
|
||||||
def min(self):
|
def min(self):
|
||||||
@ -89,7 +97,7 @@ class DateEnum(QEnum):
|
|||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Range(Values, ABC):
|
class Range(ValueGroup, ABC):
|
||||||
dtype: str = dataclasses.field(kw_only=True)
|
dtype: str = dataclasses.field(kw_only=True)
|
||||||
|
|
||||||
start: Any
|
start: Any
|
||||||
@ -327,7 +335,7 @@ class IntRange(Range):
|
|||||||
return ranges
|
return ranges
|
||||||
|
|
||||||
|
|
||||||
def values_from_json(obj) -> Values:
|
def values_from_json(obj) -> ValueGroup:
|
||||||
if isinstance(obj, list):
|
if isinstance(obj, list):
|
||||||
return QEnum(tuple(obj))
|
return QEnum(tuple(obj))
|
||||||
|
|
||||||
@ -342,7 +350,7 @@ def values_from_json(obj) -> Values:
|
|||||||
raise ValueError(f"Unknown dtype {obj['dtype']}")
|
raise ValueError(f"Unknown dtype {obj['dtype']}")
|
||||||
|
|
||||||
|
|
||||||
def convert_datatypes(q: "Qube", conversions: dict[str, Values]) -> "Qube":
|
def convert_datatypes(q: "Qube", conversions: dict[str, ValueGroup]) -> "Qube":
|
||||||
def _convert(q: "Qube") -> Iterable["Qube"]:
|
def _convert(q: "Qube") -> Iterable["Qube"]:
|
||||||
if q.key in conversions:
|
if q.key in conversions:
|
||||||
data_type = conversions[q.key]
|
data_type = conversions[q.key]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user