Source code for ooodev.utils.data_type.row_obj

from __future__ import annotations
from typing import TYPE_CHECKING
from dataclasses import dataclass, field
from weakref import ref
import numbers

try:
    # python 3.12+
    from typing import override  # noqa # type: ignore
except ImportError:
    from typing_extensions import override  # noqa # type: ignore

from ooodev.utils.validation import check
from ooodev.utils.data_type.base_int_value import BaseIntValue

if TYPE_CHECKING:
    from ooodev.utils.data_type import cell_obj as mCell


[docs]@dataclass(unsafe_hash=True) class RowObj(BaseIntValue): """ Column info. ..seealso:: - :ref:`help_ooodev.utils.data_type.row_obj.RowObj` - :ref:`ooodev.utils.data_type.row_obj.RowObj` .. versionadded:: 0.8.2 """ # region init index: int = field(init=False, repr=False, hash=False) """row Index (zero-based)""" cell_obj: "mCell.CellObj | None" = field(repr=False, hash=False, default=None) """Cell Object that instance is part of""" def __post_init__(self): # must be value of 1 or greater check(self.value > 0, "RowObj", f"Expected a value of 1 or greater. Got: {self.value}") self.index = self.value - 1 # endregion init # region static methods
[docs] @staticmethod def from_int(num: int, zero_index: bool = False) -> RowObj: """ Gets a ``RowObj`` instance from an integer. Args: num (int): Row number. zero_index (bool, optional): Determines if the row value is treated as zero index. Defaults to ``False``. Raises: AssertionError: if unable to create ``RowObj`` instance. Returns: RowObj: Cell Object """ if zero_index: check(num >= 0, f"{RowObj}", f"Expected a value of 0 or greater. Got: {num}") else: check(num >= 1, f"{RowObj}", f"Expected a value of 1 or greater. Got: {num}") try: n = num + 1 if zero_index else num return RowObj(n) except AssertionError: raise except Exception as e: raise AssertionError from e
# endregion static methods # region dunder methods def __str__(self) -> str: return str(self.value) @override def __int__(self) -> int: return self.value @override def __eq__(self, other: object) -> bool: if isinstance(other, int): return self.value == other return self.value == other.value if isinstance(other, RowObj) else False @override def __lt__(self, other: object) -> bool: try: i = int(other) # type: ignore return self.value < i except Exception: return NotImplemented @override def __le__(self, other: object) -> bool: try: i = int(other) # type: ignore return self.value <= i except Exception: return NotImplemented @override def __gt__(self, other: object) -> bool: try: i = int(other) # type: ignore return self.value > i except Exception: return NotImplemented @override def __ge__(self, other: object) -> bool: try: i = int(other) # type: ignore return self.value >= i except Exception: return NotImplemented @override def __add__(self, other: object) -> RowObj: if isinstance(other, RowObj): return RowObj.from_int(self.value + other.value) try: i = round(other) # type: ignore return RowObj.from_int(self.value + i) except TypeError: # not an int return NotImplemented except AssertionError as e: raise IndexError from e except Exception: pass return NotImplemented @override def __radd__(self, other: object) -> RowObj: # angle = sum([col1, col2, col3]) # will result in TypeError becuase sum() start with 0 # this will force a call to __radd__ return self if other == 0 else self.__add__(other) @override def __sub__(self, other: object) -> RowObj: try: if isinstance(other, RowObj): return RowObj.from_int(self.value - other.value) i = round(other) # type: ignore return RowObj.from_int(self.value - i) except TypeError: # not an int return NotImplemented except AssertionError as e: raise IndexError from e except Exception: pass return NotImplemented @override def __rsub__(self, other: object) -> RowObj: try: i = round(other) # type: ignore return self.from_int(i - self.value) except TypeError: # not an int return NotImplemented except AssertionError as e: raise IndexError from e except Exception: pass return NotImplemented @override def __mul__(self, other: object) -> RowObj: try: if isinstance(other, RowObj): return RowObj.from_int(self.value * other.value) if isinstance(other, numbers.Real): return RowObj.from_int(round(self.value * other)) # type: ignore except AssertionError as e: raise IndexError from e except Exception: pass return NotImplemented @override def __rmul__(self, other: object) -> RowObj: return self if other == 0 else self.__mul__(other) @override def __truediv__(self, other: object): try: if isinstance(other, RowObj): check(self.value != 0, f"{repr(self)}", "Cannot be divided by zero") return RowObj.from_int(round(self.value / other.value)) if isinstance(other, (int, float)): check(other != 0, f"{repr(self)}", "Cannot be divided by zero") check(self.value >= other, f"{repr(self)}", "Cannot be divided by lessor number") return RowObj.from_int(round(self.value / other)) # type: ignore except AssertionError as e: raise IndexError from e except Exception: pass return NotImplemented @override def __rtruediv__(self, other: object) -> RowObj: try: if isinstance(other, (int, float)): check(other != 0, f"{repr(self)}", "Cannot be divided by zero") check(other >= self.value, f"{repr(self)}", "Cannot be divided by lessor number") return RowObj.from_int(round(other / self.value)) # type: ignore except AssertionError as e: raise IndexError from e except Exception: pass return NotImplemented # endregion dunder methods # region properties @property def next(self) -> RowObj: """Gets the nex row""" # pylint: disable=no-member try: n = self._next # type: ignore if n() is None: raise AttributeError return n() except AttributeError: n = RowObj.from_int(self.value + 1) object.__setattr__(self, "_next", ref(n)) return self._next() # type: ignore @property def prev(self) -> RowObj: """ Gets the previous row Raises: IndexError: If previous row is out of range """ # pylint: disable=no-member try: p = self._prev # type: ignore if p() is None: raise AttributeError return p() except AttributeError: try: p = RowObj.from_int(self.value - 1) object.__setattr__(self, "_prev", ref(p)) except AssertionError as e: raise IndexError from e return self._prev() # type: ignore
# endregion properties