def distance_to_next_change(boxes: List[Any], idx: int) -> Optional[int]:
    """Given a sequence and an index, find the number of elements to the next
    value that's different from the current one.
    """
    remboxes = boxes[idx:] + [None]
    dist = fn.ilen(fn.takewhile(lambda b: b == boxes[idx], remboxes))
    if remboxes[dist] is None:
        return None
    return dist
Exemple #2
0
def read_config_header(filepath, defaults=None, encoding=DEFAULT_ENCODING):
    filepath = Path(filepath)
    if not has_config_header(filepath):
        return defaults.copy() if defaults else {}
    else:
        with open(filepath, mode="r", encoding=DEFAULT_ENCODING) as fi:
            header = "".join(
                fn.takewhile(
                    fn.none_fn(
                        fn.rpartial(str.startswith, "---\n"),
                        fn.rpartial(str.startswith, "...\n"),
                    ),
                    fn.rest(fi),
                )
            )
        return parse_config(header, defaults)
Exemple #3
0

def to_digits(number: int) -> Iterable[int]:
    return map(int, str(number))


def is_bouncy(number: int) -> bool:
    pairwise_digits = list(pairwise(to_digits(number)))
    return (not all(a >= b for (a, b) in pairwise_digits)) \
       and (not all(a <= b for (a, b) in pairwise_digits))


State = namedtuple('State', 'i num_of_bouncy proportion_of_bouncy')


def step(prev: State) -> State:
    i = prev.i + 1
    num_of_bouncy = int(is_bouncy(i)) + prev.num_of_bouncy
    return State(i, num_of_bouncy, proportion_of_bouncy=num_of_bouncy / i)


if __name__ == '__main__':
    initial_state = State(i=1, num_of_bouncy=0, proportion_of_bouncy=0)

    result = rcompose(
        lambda: iterate(step, initial_state),
        lambda xs: takewhile(lambda x: x.proportion_of_bouncy <= 0.99, xs),
        last)()

    print(result)
def competence(request):
    def same_as_canonical(raw_annotation):
        return is_samples_concordant(raw_annotation, raw_annotation.canonical)

    if request.user.is_competent:
        return redirect(validate)

    if request.method == 'POST':
        canonical_id = request.POST['canonical_id']
        data = {
            'user_id': request.user.id,
            'column': request.POST['column'],
            'regex': request.POST['regex'],
            'annotations': dict(json.loads(request.POST['values'])),
            'is_active': False,
            'by_incompetent': True,
        }

        # Save validation marking by_incompetent
        try:
            save_validation(canonical_id, data)
        except AnnotationError as err:
            messages.error(request, str(err))
        return redirect(competence)

    # Check how many tries and progress = number of successful tries in a row
    annotations = RawSeriesAnnotation.objects.filter(created_by=request.user, by_incompetent=True) \
                                     .order_by('-id')[:5] \
                                     .prefetch_related('sample_annotations', 'canonical',
                                                       'canonical__sample_annotations')
    first_try = len(annotations) == 0
    annotations = list(takewhile(same_as_canonical, annotations))
    progress = len(annotations)

    # 5 successful tries in a row is test pass
    if progress >= 5:
        request.user.is_competent = True
        request.user.save()
        messages.success(
            request, '''Congratulations! You passed competence test.<br>
                                     You can now annotate and validate series.'''
        )
        return redirect(validate)

    # Welcome, progress and fail messages
    if progress == 0 and first_try:
        messages.info(
            request, '''Welcome to competence test!<br>
                                  You need to annotate 5 series in a row correctly to pass.'''
        )
    elif progress == 0 and not first_try:
        messages.error(
            request, '''This one was wrong, sorry.<br>
                                   Starting from zero with fresh series.''')
    elif progress == 4:
        messages.success(request,
                         '''You are almost there! Here is the last one.''')
    elif progress == 3:
        messages.success(request,
                         '''Good progress, only 2 annotations left.''')
    else:
        messages.success(request,
                         '''Correct! %d series to go.''' % (5 - progress))

    # Select canonical annotation to test against
    # NOTE: several conditions play here:
    #         - exclude annotations seen before
    #         - only use agreed upon ones (best_cohens_kappa = 1 means there are 2 concordant annos)
    #         - first 3 tries select non-controversial annotations (fleiss_kappa = 1)
    #         - exclude tags seen in this test run
    #         - last 2 tries select less obvious annotations (fleiss_kappa < 1)
    #         - 2 of all tests should use captive tags
    qs = SeriesAnnotation.objects.exclude(raw_annotations__created_by=request.user) \
                                 .filter(best_cohens_kappa=1) \
                                 .select_related('series_tag', 'series_tag__tag')

    # These conds are lifted until some test material is found
    conds = [Q(fleiss_kappa=1) if progress < 3 else Q(fleiss_kappa__lt=1)]
    seen_tags = [a.tag_id for a in annotations]
    if seen_tags:
        conds += [~Q(tag__in=seen_tags)]
    if progress == 0:
        conds += [Q(captive=False)]
    else:
        captive_left = 2 - sum(a.canonical.captive for a in annotations)
        conds += [Q(captive=random.randint(0, 5 - progress) < captive_left)]

    canonical = get_sample(qs, conds)
    if canonical is None:
        messages.error(request,
                       '''Too many tries, we are out of test material.''')
        return redirect(validate)

    samples, columns = fetch_annotation_data(canonical.series_id,
                                             canonical.platform_id,
                                             blind=BLIND_FIELDS)

    return {
        'canonical': canonical,
        'series': canonical.series,
        'tag': canonical.tag,
        'columns': columns,
        'samples': samples,
        'progress': progress
    }
Exemple #5
0
 def sees_stars(self):
     parents = takewhile(bool, iterate(lambda s: s.parent, self))
     return any(s.has_stars for s in parents)