def binary_search(seq, f, target):
    """Find no such that f(seq[no-1]) <= target and f(seq[no]) > target.

    If target < f(seq[0]), return 0
    If target > f(seq[-1]), return len(seq)

    Assume f(seq[no]) < f(seq[no+1]).

    The integer result is useful for indexing the array.

    Args:
        seq: sequence of inputs on which to act
        f: function that returns a comparable when called on any input
        target: value

    Returns: index of item in seq meeting search requirements
    """
    if not seq or f(seq[0]) > target:
        return 0
    elif f(seq[-1]) < target:
        return len(seq)
    upper = len(seq)
    lower = 0
    while (upper - lower) > 1:
        current = (upper + lower) // 2
        next_val = f(seq[current])
        if next_val > target:
            upper = current
        elif next_val <= target:
            lower = current
    return upper