Duration.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. """Duration module."""
  2. import functools
  3. import operator
  4. from matplotlib import _api
  5. class Duration:
  6. """Class Duration in development."""
  7. allowed = ["ET", "UTC"]
  8. def __init__(self, frame, seconds):
  9. """
  10. Create a new Duration object.
  11. = ERROR CONDITIONS
  12. - If the input frame is not in the allowed list, an error is thrown.
  13. = INPUT VARIABLES
  14. - frame The frame of the duration. Must be 'ET' or 'UTC'
  15. - seconds The number of seconds in the Duration.
  16. """
  17. _api.check_in_list(self.allowed, frame=frame)
  18. self._frame = frame
  19. self._seconds = seconds
  20. def frame(self):
  21. """Return the frame the duration is in."""
  22. return self._frame
  23. def __abs__(self):
  24. """Return the absolute value of the duration."""
  25. return Duration(self._frame, abs(self._seconds))
  26. def __neg__(self):
  27. """Return the negative value of this Duration."""
  28. return Duration(self._frame, -self._seconds)
  29. def seconds(self):
  30. """Return the number of seconds in the Duration."""
  31. return self._seconds
  32. def __bool__(self):
  33. return self._seconds != 0
  34. def _cmp(self, op, rhs):
  35. """
  36. Check that *self* and *rhs* share frames; compare them using *op*.
  37. """
  38. self.checkSameFrame(rhs, "compare")
  39. return op(self._seconds, rhs._seconds)
  40. __eq__ = functools.partialmethod(_cmp, operator.eq)
  41. __ne__ = functools.partialmethod(_cmp, operator.ne)
  42. __lt__ = functools.partialmethod(_cmp, operator.lt)
  43. __le__ = functools.partialmethod(_cmp, operator.le)
  44. __gt__ = functools.partialmethod(_cmp, operator.gt)
  45. __ge__ = functools.partialmethod(_cmp, operator.ge)
  46. def __add__(self, rhs):
  47. """
  48. Add two Durations.
  49. = ERROR CONDITIONS
  50. - If the input rhs is not in the same frame, an error is thrown.
  51. = INPUT VARIABLES
  52. - rhs The Duration to add.
  53. = RETURN VALUE
  54. - Returns the sum of ourselves and the input Duration.
  55. """
  56. # Delay-load due to circular dependencies.
  57. import matplotlib.testing.jpl_units as U
  58. if isinstance(rhs, U.Epoch):
  59. return rhs + self
  60. self.checkSameFrame(rhs, "add")
  61. return Duration(self._frame, self._seconds + rhs._seconds)
  62. def __sub__(self, rhs):
  63. """
  64. Subtract two Durations.
  65. = ERROR CONDITIONS
  66. - If the input rhs is not in the same frame, an error is thrown.
  67. = INPUT VARIABLES
  68. - rhs The Duration to subtract.
  69. = RETURN VALUE
  70. - Returns the difference of ourselves and the input Duration.
  71. """
  72. self.checkSameFrame(rhs, "sub")
  73. return Duration(self._frame, self._seconds - rhs._seconds)
  74. def __mul__(self, rhs):
  75. """
  76. Scale a UnitDbl by a value.
  77. = INPUT VARIABLES
  78. - rhs The scalar to multiply by.
  79. = RETURN VALUE
  80. - Returns the scaled Duration.
  81. """
  82. return Duration(self._frame, self._seconds * float(rhs))
  83. __rmul__ = __mul__
  84. def __str__(self):
  85. """Print the Duration."""
  86. return f"{self._seconds:g} {self._frame}"
  87. def __repr__(self):
  88. """Print the Duration."""
  89. return f"Duration('{self._frame}', {self._seconds:g})"
  90. def checkSameFrame(self, rhs, func):
  91. """
  92. Check to see if frames are the same.
  93. = ERROR CONDITIONS
  94. - If the frame of the rhs Duration is not the same as our frame,
  95. an error is thrown.
  96. = INPUT VARIABLES
  97. - rhs The Duration to check for the same frame
  98. - func The name of the function doing the check.
  99. """
  100. if self._frame != rhs._frame:
  101. raise ValueError(
  102. f"Cannot {func} Durations with different frames.\n"
  103. f"LHS: {self._frame}\n"
  104. f"RHS: {rhs._frame}")