Ejemplo n.º 1
0
 def get_nearest_prev_point(self, point):
     """Return the largest point < some arbitrary point."""
     if self.is_on_sequence(point):
         return self.get_prev_point(point)
     p_iso_point = point_parse(point.value)
     p_iso_excl = None
     if self.exclusion:
         p_iso_excl = point_parse(self.exclusion.value)
     prev_iso_point = None
     for recurrence_iso_point in self.recurrence:
         if (recurrence_iso_point > p_iso_point
                 or (p_iso_excl and recurrence_iso_point == p_iso_excl)):
             # Technically, >=, but we already test for this above.
             break
         prev_iso_point = recurrence_iso_point
     if prev_iso_point is None:
         return None
     nearest_point = ISO8601Point(str(prev_iso_point))
     if nearest_point == point:
         raise SequenceDegenerateError(self.recurrence,
                                       SuiteSpecifics.DUMP_FORMAT,
                                       nearest_point, point)
     if self.exclusion and nearest_point == self.exclusion:
         return self.get_prev_point(nearest_point)
     return nearest_point
Ejemplo n.º 2
0
    def get_nearest_prev_point(self, point):
        """Return the largest point < some arbitrary point."""
        if self.is_on_sequence(point):
            return self.get_prev_point(point)
        p_iso_point = point_parse(point.value)
        prev_cycle_point = None

        for recurrence_iso_point in self.recurrence:

            # Is recurrence point greater than arbitrary point?
            if recurrence_iso_point > p_iso_point:
                break
            recurrence_cycle_point = ISO8601Point(str(recurrence_iso_point))
            if self.exclusions and recurrence_cycle_point in self.exclusions:
                break
            prev_cycle_point = recurrence_cycle_point

        if prev_cycle_point is None:
            return None
        if prev_cycle_point == point:
            raise SequenceDegenerateError(self.recurrence,
                                          SuiteSpecifics.DUMP_FORMAT,
                                          prev_cycle_point, point)
        # Check all exclusions
        if self.exclusions and prev_cycle_point in self.exclusions:
            return self.get_prev_point(prev_cycle_point)
        return prev_cycle_point
Ejemplo n.º 3
0
 def get_next_point_on_sequence(self, point):
     """Return the on-sequence point > point assuming that point is
     on-sequence, or None if out of bounds."""
     result = None
     next_point = self.recurrence.get_next(point_parse(point.value))
     if next_point:
         result = ISO8601Point(str(next_point))
         if result == point:
             raise SequenceDegenerateError(self.recurrence,
                                           SuiteSpecifics.DUMP_FORMAT,
                                           point, result)
     return result
Ejemplo n.º 4
0
 def get_prev_point(self, point):
     """Return the previous point < point, or None if out of bounds."""
     # may be None if out of the recurrence bounds
     res = None
     prev_point = self.recurrence.get_prev(point_parse(point.value))
     if prev_point:
         res = ISO8601Point(str(prev_point))
         if res == point:
             raise SequenceDegenerateError(self.recurrence,
                                           SuiteSpecifics.DUMP_FORMAT, res,
                                           point)
     return res
Ejemplo n.º 5
0
    def _check_and_cache_next_point(self, point, next_point):
        """Verify and cache the get_next_point return info."""
        # Verify next_point != point.
        if next_point == point:
            raise SequenceDegenerateError(self.recurrence,
                                          SuiteSpecifics.DUMP_FORMAT,
                                          next_point, point)

        # Cache the answer for point -> next_point.
        if (len(self._cached_next_point_values) > self._MAX_CACHED_POINTS):
            self._cached_next_point_values.popitem()
        self._cached_next_point_values[point.value] = next_point.value

        # Cache next_point as a valid starting point for this recurrence.
        if (len(self._cached_next_point_values) > self._MAX_CACHED_POINTS):
            self._cached_recent_valid_points.pop(0)
        self._cached_recent_valid_points.append(next_point)
Ejemplo n.º 6
0
 def get_prev_point(self, point):
     """Return the previous point < point, or None if out of bounds."""
     # may be None if out of the recurrence bounds
     res = None
     prev_point = self.recurrence.get_prev(point_parse(point.value))
     if prev_point:
         res = ISO8601Point(str(prev_point))
         if res == point:
             raise SequenceDegenerateError(self.recurrence,
                                           SuiteSpecifics.DUMP_FORMAT, res,
                                           point)
         # Check if res point is in the list of exclusions
         # If so, check the previous point by recursion.
         # Once you have found a point that is *not* in the exclusion
         # list, you can return it.
         if self.exclusions and res in self.exclusions:
             return self.get_prev_point(res)
     return res
Ejemplo n.º 7
0
 def get_next_point(self, point):
     """Return the next point > p, or None if out of bounds."""
     try:
         return ISO8601Point(self._cached_next_point_values[point.value])
     except KeyError:
         pass
     p_iso_point = point_parse(point.value)
     for recurrence_iso_point in self.recurrence:
         if recurrence_iso_point > p_iso_point:
             next_point_value = str(recurrence_iso_point)
             if (len(self._cached_next_point_values) >
                     self._MAX_CACHED_POINTS):
                 self._cached_next_point_values.popitem()
             self._cached_next_point_values[point.value] = next_point_value
             next_point = ISO8601Point(next_point_value)
             if next_point == point:
                 raise SequenceDegenerateError(self.recurrence,
                                               SuiteSpecifics.DUMP_FORMAT,
                                               nearest_point, point)
             return next_point
     return None