Skip to content

Module unitexpr.unit_dict

Dictionary intended to be used with numeric value types.

Adds support for arithmetic operators.

View Source
"""

Dictionary intended to be used with numeric value types.

Adds support for arithmetic operators.

"""

from __future__ import annotations

class UnitDict(dict):

    """

    Extends `dict` adding support for the arithmetic

    operators `+`, `-`, scalar multiplication.

    * The value type must implement the operators above.

    * Strips keys with value zero.

    """

    # def __init__(self, *args, **kwargs):

    #    super().__init__(float, *args, **kwargs)

    def __sub__(self: UnitDict, other: UnitDict) -> UnitDict:

        """

        Subtracts the values of entries with the same key andipyt

        returns the resulting

        dictionary. Keys with value zero are deleted.

        Note: Returns a new object.

        """

        obj = dict(self)

        for term in other:

            tmp = obj[term] = obj.get(term, 0.0) - other[term]

            if not tmp:

                del obj[term]

        return self.__class__(obj)

    def copy(self) -> UnitDict:

        """

        Returns a new `UnitDict` object containing the same entries as `self`.

        """

        return self.__class__(self)

    def __add__(self: UnitDict, other: UnitDict) -> UnitDict:

        """

        Adds the values of entries with the same key and returns the resulting

        dictionary. Keys with value zero are deleted.

        Note: Returns a new object.

        """

        obj = UnitDict(self)

        for term in other:

            tmp = obj[term] = obj.get(term, 0.0) + other[term]

            if not tmp:

                del obj[term]

        return obj

    def __mul__(self: UnitDict, other: float) -> UnitDict:

        """

        Multiplies the value of each entry with `other` and returns the

        resulting dictionary.

        Note: Returns a new object.

        """

        if other == 0.0:

            return UnitDict()

        obj = UnitDict(self)

        for key in obj:

            obj[key] *= other

        return obj

    def __rmul__(self, other: float) -> UnitDict:

        """

        Multiplies `other` with the value of each entry and returns the

        resulting dictionary.

        Note: Returns a new object.

        """

        return self.__mul__(other)

    def __repr__(self) -> str:

        """

        Returns a string representation of self.

        """

        return self.__class__.__name__ + f"({super().__repr__()})"

    def __neg__(self) -> UnitDict:

        """

        Negates the dictionary values and returns the resulting

        dictionary.

        Note: Returns a new object.

        """

        obj = UnitDict(self)

        for key in obj:

            obj[key] *= -1

        return obj

    def filter_value(self, value) -> UnitDict:

        """

        Remove all entries with matching `value` and returns the resulting

        dictionary.

        Note: Returns a new object.

        """

        obj = UnitDict(self)

        for key in self.keys():

            if obj[key] == value:

                del obj[key]

        return obj

class ImmutableUnitDict(UnitDict):

    """

    Immutable class that extends `UnitDict` with support for the arithmetic

    operators `+`, `-`, scalar multiplication, and

    `**`.

    Note: The value type must implement the operators above.

    """

    def __add__(self: ImmutableUnitDict, other: UnitDict) -> ImmutableUnitDict:

        """

        Adds the values of entries with the same key and returns the resulting

        dictionary. Keys with value zero are deleted.

        Note: Returns a new object.

        """

        obj = dict(self)

        for term in other:

            tmp = obj[term] = obj.get(term, 0.0) + other[term]

            if not tmp:

                del obj[term]

        return ImmutableUnitDict(obj)

    def __sub__(self: ImmutableUnitDict, other: UnitDict) -> UnitDict:

        """

        Subtracts the values of entries with the same key and

        returns the resulting

        dictionary. Keys with value zero are deleted.

        Note: Returns a new object.

        """

        obj = dict(self)

        for term in other:

            tmp = obj[term] = obj.get(term, 0.0) - other[term]

            if not tmp:

                del obj[term]

        return ImmutableUnitDict(obj)

    def __rmul__(self, other: float) -> UnitDict:

        """

        Multiplies `other` with the value of each entry and returns the

        resulting dictionary.

        Note: Returns a new object.

        """

        return self.__mul__(other)

    def __mul__(self, other: float) -> ImmutableUnitDict:

        """

        Multiplies the value of each entry with `other` and returns the

        resulting dictionary.

        Note: Returns a new object.

        """

        if other == 0.0:

            return ImmutableUnitDict()

        obj = dict(self)

        for key in obj:

            obj[key] *= other

        return ImmutableUnitDict(obj)

    def __neg__(self) -> ImmutableUnitDict:

        obj = dict(self)

        for key in obj:

            obj[key] *= -1

        return ImmutableUnitDict(obj)

    def filter_value(self, value) -> ImmutableUnitDict:

        """

        Removes all entries with matching `value` and returns the resulting

        dictionary.

        Note: Returns a new object.

        """

        obj = dict(self)

        for key in self:

            if obj[key] == value:

                del obj[key]

        return ImmutableUnitDict(obj)

    def __setitem__(self, key, value) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not "

            + "support item assignment."

        )

    def __delitem__(self, value) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not "

            + "support item deletion."

        )

    def clear(self) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object " + "cannot be cleared."

        )

    def update(self, *args, **kwargs) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object " + "cannot be updated."

        )

    def setdefault(self, key, default) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not "

            + "support default values."

        )

    def pop(self) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not " + "support `pop`."

        )

    def popitem(self) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not "

            + "support `popitem`."

        )

Classes

ImmutableUnitDict

class ImmutableUnitDict(
    /,
    *args,
    **kwargs
)
View Source
class ImmutableUnitDict(UnitDict):

    """

    Immutable class that extends `UnitDict` with support for the arithmetic

    operators `+`, `-`, scalar multiplication, and

    `**`.

    Note: The value type must implement the operators above.

    """

    def __add__(self: ImmutableUnitDict, other: UnitDict) -> ImmutableUnitDict:

        """

        Adds the values of entries with the same key and returns the resulting

        dictionary. Keys with value zero are deleted.

        Note: Returns a new object.

        """

        obj = dict(self)

        for term in other:

            tmp = obj[term] = obj.get(term, 0.0) + other[term]

            if not tmp:

                del obj[term]

        return ImmutableUnitDict(obj)

    def __sub__(self: ImmutableUnitDict, other: UnitDict) -> UnitDict:

        """

        Subtracts the values of entries with the same key and

        returns the resulting

        dictionary. Keys with value zero are deleted.

        Note: Returns a new object.

        """

        obj = dict(self)

        for term in other:

            tmp = obj[term] = obj.get(term, 0.0) - other[term]

            if not tmp:

                del obj[term]

        return ImmutableUnitDict(obj)

    def __rmul__(self, other: float) -> UnitDict:

        """

        Multiplies `other` with the value of each entry and returns the

        resulting dictionary.

        Note: Returns a new object.

        """

        return self.__mul__(other)

    def __mul__(self, other: float) -> ImmutableUnitDict:

        """

        Multiplies the value of each entry with `other` and returns the

        resulting dictionary.

        Note: Returns a new object.

        """

        if other == 0.0:

            return ImmutableUnitDict()

        obj = dict(self)

        for key in obj:

            obj[key] *= other

        return ImmutableUnitDict(obj)

    def __neg__(self) -> ImmutableUnitDict:

        obj = dict(self)

        for key in obj:

            obj[key] *= -1

        return ImmutableUnitDict(obj)

    def filter_value(self, value) -> ImmutableUnitDict:

        """

        Removes all entries with matching `value` and returns the resulting

        dictionary.

        Note: Returns a new object.

        """

        obj = dict(self)

        for key in self:

            if obj[key] == value:

                del obj[key]

        return ImmutableUnitDict(obj)

    def __setitem__(self, key, value) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not "

            + "support item assignment."

        )

    def __delitem__(self, value) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not "

            + "support item deletion."

        )

    def clear(self) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object " + "cannot be cleared."

        )

    def update(self, *args, **kwargs) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object " + "cannot be updated."

        )

    def setdefault(self, key, default) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not "

            + "support default values."

        )

    def pop(self) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not " + "support `pop`."

        )

    def popitem(self) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not "

            + "support `popitem`."

        )

Ancestors (in MRO)

  • unitexpr.unit_dict.UnitDict
  • builtins.dict

Methods

clear

def clear(
    self
) -> 'None'

Not supported. Immutable object.

View Source
    def clear(self) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object " + "cannot be cleared."

        )

copy

def copy(
    self
) -> 'UnitDict'

Returns a new UnitDict object containing the same entries as self.

View Source
    def copy(self) -> UnitDict:

        """

        Returns a new `UnitDict` object containing the same entries as `self`.

        """

        return self.__class__(self)

filter_value

def filter_value(
    self,
    value
) -> 'ImmutableUnitDict'

Removes all entries with matching value and returns the resulting

dictionary.

Note: Returns a new object.

View Source
    def filter_value(self, value) -> ImmutableUnitDict:

        """

        Removes all entries with matching `value` and returns the resulting

        dictionary.

        Note: Returns a new object.

        """

        obj = dict(self)

        for key in self:

            if obj[key] == value:

                del obj[key]

        return ImmutableUnitDict(obj)

fromkeys

def fromkeys(
    iterable,
    value=None,
    /
)

Create a new dictionary with keys from iterable and values set to value.

get

def get(
    self,
    key,
    default=None,
    /
)

Return the value for key if key is in the dictionary, else default.

items

def items(
    ...
)

D.items() -> a set-like object providing a view on D's items

keys

def keys(
    ...
)

D.keys() -> a set-like object providing a view on D's keys

pop

def pop(
    self
) -> 'None'

Not supported. Immutable object.

View Source
    def pop(self) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not " + "support `pop`."

        )

popitem

def popitem(
    self
) -> 'None'

Not supported. Immutable object.

View Source
    def popitem(self) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not "

            + "support `popitem`."

        )

setdefault

def setdefault(
    self,
    key,
    default
) -> 'None'

Not supported. Immutable object.

View Source
    def setdefault(self, key, default) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object does not "

            + "support default values."

        )

update

def update(
    self,
    *args,
    **kwargs
) -> 'None'

Not supported. Immutable object.

View Source
    def update(self, *args, **kwargs) -> None:

        """

        Not supported. Immutable object.

        """

        raise TypeError(

            f"'{self.__class__.__name__}' object " + "cannot be updated."

        )

values

def values(
    ...
)

D.values() -> an object providing a view on D's values

UnitDict

class UnitDict(
    /,
    *args,
    **kwargs
)
View Source
class UnitDict(dict):

    """

    Extends `dict` adding support for the arithmetic

    operators `+`, `-`, scalar multiplication.

    * The value type must implement the operators above.

    * Strips keys with value zero.

    """

    # def __init__(self, *args, **kwargs):

    #    super().__init__(float, *args, **kwargs)

    def __sub__(self: UnitDict, other: UnitDict) -> UnitDict:

        """

        Subtracts the values of entries with the same key andipyt

        returns the resulting

        dictionary. Keys with value zero are deleted.

        Note: Returns a new object.

        """

        obj = dict(self)

        for term in other:

            tmp = obj[term] = obj.get(term, 0.0) - other[term]

            if not tmp:

                del obj[term]

        return self.__class__(obj)

    def copy(self) -> UnitDict:

        """

        Returns a new `UnitDict` object containing the same entries as `self`.

        """

        return self.__class__(self)

    def __add__(self: UnitDict, other: UnitDict) -> UnitDict:

        """

        Adds the values of entries with the same key and returns the resulting

        dictionary. Keys with value zero are deleted.

        Note: Returns a new object.

        """

        obj = UnitDict(self)

        for term in other:

            tmp = obj[term] = obj.get(term, 0.0) + other[term]

            if not tmp:

                del obj[term]

        return obj

    def __mul__(self: UnitDict, other: float) -> UnitDict:

        """

        Multiplies the value of each entry with `other` and returns the

        resulting dictionary.

        Note: Returns a new object.

        """

        if other == 0.0:

            return UnitDict()

        obj = UnitDict(self)

        for key in obj:

            obj[key] *= other

        return obj

    def __rmul__(self, other: float) -> UnitDict:

        """

        Multiplies `other` with the value of each entry and returns the

        resulting dictionary.

        Note: Returns a new object.

        """

        return self.__mul__(other)

    def __repr__(self) -> str:

        """

        Returns a string representation of self.

        """

        return self.__class__.__name__ + f"({super().__repr__()})"

    def __neg__(self) -> UnitDict:

        """

        Negates the dictionary values and returns the resulting

        dictionary.

        Note: Returns a new object.

        """

        obj = UnitDict(self)

        for key in obj:

            obj[key] *= -1

        return obj

    def filter_value(self, value) -> UnitDict:

        """

        Remove all entries with matching `value` and returns the resulting

        dictionary.

        Note: Returns a new object.

        """

        obj = UnitDict(self)

        for key in self.keys():

            if obj[key] == value:

                del obj[key]

        return obj

Ancestors (in MRO)

  • builtins.dict

Descendants

  • unitexpr.unit_dict.ImmutableUnitDict

Methods

clear

def clear(
    ...
)

D.clear() -> None. Remove all items from D.

copy

def copy(
    self
) -> 'UnitDict'

Returns a new UnitDict object containing the same entries as self.

View Source
    def copy(self) -> UnitDict:

        """

        Returns a new `UnitDict` object containing the same entries as `self`.

        """

        return self.__class__(self)

filter_value

def filter_value(
    self,
    value
) -> 'UnitDict'

Remove all entries with matching value and returns the resulting

dictionary.

Note: Returns a new object.

View Source
    def filter_value(self, value) -> UnitDict:

        """

        Remove all entries with matching `value` and returns the resulting

        dictionary.

        Note: Returns a new object.

        """

        obj = UnitDict(self)

        for key in self.keys():

            if obj[key] == value:

                del obj[key]

        return obj

fromkeys

def fromkeys(
    iterable,
    value=None,
    /
)

Create a new dictionary with keys from iterable and values set to value.

get

def get(
    self,
    key,
    default=None,
    /
)

Return the value for key if key is in the dictionary, else default.

items

def items(
    ...
)

D.items() -> a set-like object providing a view on D's items

keys

def keys(
    ...
)

D.keys() -> a set-like object providing a view on D's keys

pop

def pop(
    ...
)

D.pop(k[,d]) -> v, remove specified key and return the corresponding value.

If key is not found, default is returned if given, otherwise KeyError is raised

popitem

def popitem(
    self,
    /
)

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

setdefault

def setdefault(
    self,
    key,
    default=None,
    /
)

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update

def update(
    ...
)

D.update([E, ]**F) -> None. Update D from dict/iterable E and F.

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values

def values(
    ...
)

D.values() -> an object providing a view on D's values