def labeled_neighbor(self, obj, judge, back=False):
        """Returns the id of the "closest" labeled object to the one provided.
        Notes:
            - By "closest", it's mean the distance of the id numbers.
            - Works both for TextSegment and for IEDocument
            - If back is True, it's picked the previous item, otherwise, the next one.
            - It's assumed that the obj provided HAS labeled evidence already. If not,
              it's not possible to determine what is next. In such case, the id of the
              last labeled object will be returned.

            - If asking "next" and obj is currently the last, his id will be returned.
            - If asking "prev" and obj is currently the first, his id will be returned.
        """

        filters = dict(
            judge__isnull=False,
            label__isnull=False,
            relation=self,
        )
        if judge is not None:
            filters["judge"] = judge
        judge_labels = EvidenceLabel.objects.filter(**filters)

        if isinstance(obj, TextSegment):
            segments = self._matching_text_segments()
            segments = segments.filter(evidence_relations__labels__relation=self)
            candidates_with_label = judge_labels.values_list("evidence_candidate__segment", flat=True)
            segments = segments.filter(id__in=candidates_with_label).distinct()
            ids = list(segments.values_list('id', flat=True).order_by('id'))
        elif isinstance(obj, IEDocument):
            ids = sorted(set(judge_labels.values_list(
                'evidence_candidate__segment__document_id', flat=True)
            ))
        else:
            ids = []
        if not ids:
            return None
        try:
            base_idx = ids.index(obj.id)
        except __HOLE__:
            # the base-object provided is not listed... Returning the base-object
            # Returning last in list
            return ids[-1]
        else:
            if back:
                if base_idx == 0:
                    # there is no previous one. Returning same.
                    return obj.id
                else:
                    return ids[base_idx - 1]
            else:
                if base_idx == len(ids) - 1:
                    # there is no next one. Returning same.
                    return obj.id
                else:
                    return ids[base_idx + 1]
dataset/ETHPy150Open machinalis/iepy/iepy/data/models.py/Relation.labeled_neighbor