From 48444cc3ce6e084119071c42926c5f9a912897ab Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 27 Feb 2025 16:46:16 +0000 Subject: [PATCH] Rename Values -> ValueGroup --- src/python/qubed/Qube.py | 6 +++--- src/python/qubed/node_types.py | 4 ++-- src/python/qubed/set_operations.py | 10 ++++++---- src/python/qubed/value_types.py | 24 ++++++++++++++++-------- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/python/qubed/Qube.py b/src/python/qubed/Qube.py index e0a19e9..0ae94e9 100644 --- a/src/python/qubed/Qube.py +++ b/src/python/qubed/Qube.py @@ -13,7 +13,7 @@ from .tree_formatters import ( node_tree_to_html, 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) @@ -26,7 +26,7 @@ class Qube: return self.data.key @property - def values(self) -> Values: + def values(self) -> ValueGroup: return self.data.values @property @@ -51,7 +51,7 @@ class Qube: return self.data.summary() @classmethod - def make(cls, key: str, values: Values, children, **kwargs) -> "Qube": + def make(cls, key: str, values: ValueGroup, children, **kwargs) -> "Qube": return cls( data=NodeData(key, values, metadata=kwargs.get("metadata", frozendict())), children=tuple(sorted(children, key=lambda n: ((n.key, n.values.min())))), diff --git a/src/python/qubed/node_types.py b/src/python/qubed/node_types.py index b7f8651..bb819dc 100644 --- a/src/python/qubed/node_types.py +++ b/src/python/qubed/node_types.py @@ -3,13 +3,13 @@ from typing import Hashable from frozendict import frozendict -from .value_types import Values +from .value_types import ValueGroup @dataclass(frozen=False, eq=True, order=True, unsafe_hash=True) class NodeData: key: str - values: Values + values: ValueGroup metadata: dict[str, tuple[Hashable, ...]] = field( default_factory=frozendict, compare=False ) diff --git a/src/python/qubed/set_operations.py b/src/python/qubed/set_operations.py index 0b3a694..9f07022 100644 --- a/src/python/qubed/set_operations.py +++ b/src/python/qubed/set_operations.py @@ -8,7 +8,7 @@ from typing import TYPE_CHECKING, Iterable from frozendict import frozendict from .node_types import NodeData -from .value_types import QEnum, Values +from .value_types import QEnum, ValueGroup if TYPE_CHECKING: from .qube import Qube @@ -22,8 +22,8 @@ class SetOperation(Enum): def fused_set_operations( - A: "Values", B: "Values" -) -> tuple[list[Values], list[Values], list[Values]]: + A: "ValueGroup", B: "ValueGroup" +) -> tuple[list[ValueGroup], list[ValueGroup], list[ValueGroup]]: if isinstance(A, QEnum) and isinstance(B, QEnum): set_A, set_B = 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): set_A, set_B = set(A), set(B) intersection = set_A & set_B diff --git a/src/python/qubed/value_types.py b/src/python/qubed/value_types.py index 3fddadd..33c46e6 100644 --- a/src/python/qubed/value_types.py +++ b/src/python/qubed/value_types.py @@ -9,33 +9,41 @@ if TYPE_CHECKING: @dataclass(frozen=True) -class Values(ABC): +class ValueGroup(ABC): @abstractmethod def summary(self) -> str: + "Provide a string summary of the value group." pass @abstractmethod def __len__(self) -> int: + "Return how many values this group contains." pass @abstractmethod def __contains__(self, value: Any) -> bool: + "Given a value, coerce to the value type and determine if it is in the value group." pass @abstractmethod def __iter__(self) -> Iterable[Any]: + "Iterate over the values in the group." pass + @classmethod @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 @abstractmethod def min(self): + "Return the minimum value in the group." pass @abstractmethod - def to_json(self): + def to_json(self) -> dict: + "Return a JSON serializable representation of the value group." pass @@ -44,7 +52,7 @@ EnumValuesType = FrozenSet[T] @dataclass(frozen=True, order=True) -class QEnum(Values): +class QEnum(ValueGroup): """ The simplest kind of key value is just a list of strings. summary -> string1/string2/string.... @@ -70,7 +78,7 @@ class QEnum(Values): def __contains__(self, value: Any) -> bool: 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))] def min(self): @@ -89,7 +97,7 @@ class DateEnum(QEnum): @dataclass(frozen=True) -class Range(Values, ABC): +class Range(ValueGroup, ABC): dtype: str = dataclasses.field(kw_only=True) start: Any @@ -327,7 +335,7 @@ class IntRange(Range): return ranges -def values_from_json(obj) -> Values: +def values_from_json(obj) -> ValueGroup: if isinstance(obj, list): return QEnum(tuple(obj)) @@ -342,7 +350,7 @@ def values_from_json(obj) -> Values: 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"]: if q.key in conversions: data_type = conversions[q.key]