def score_by_accuracy(truth, predictions, cutoff=0.5, binder_weight=0.5):
    """
    Score a set of predictions by their accuracy.

    Parameters
    ----------
    cutoff : float
        the value separating 'binders' predictions and 'nonbinder' predictions
        (defaults to 0.5) - Predictions are considered accurate if they land on
        the same side of the cutoff value as the truth.

    binder_weight : float
        the fraction that the binder score contributes to the overall score -
        The prediction accuracy for binders and nonbinders is considered
        separately and then combined according to this weight.

    Returns
    -------
    float
        a score between 0 and 1
    """
    correctness = [(t > cutoff) == (p > cutoff)
                   for (t, p) in zip(truth, predictions)]

    def score_for_truth(truth_value):
        filtered = [
            c for (c, t) in zip(correctness, truth) if t == truth_value
        ]
        return sum(1 for c in filtered if c) / len(filtered) if filtered else 0

    return score_for_truth(1) * binder_weight + score_for_truth(0) * (
        1 - binder_weight)