import random

##x = 7
##L = [3, 5, 8, 7, 12]
##
##result = 0
##for y in L:
##    if y <= x:
##        result += 1
##
##print(result)
##
##result = sum([1 for y in L if y <= x])
##print(result)
##
##result = sum([y <= x for y in L])
##print(result)

CHECK_USER_ARGUMENTS = True

def rank(x, L):
    '''
    Returner antal værdier i L som er <= x.

    L er en sorteret liste af heltal.
    x er et heltal.
    Returnerer i, hvor 0 <= i <= len(L), og alle elementer
    i L[:i] <= x, og alle elementer i L[i:] > x.
    '''

    if CHECK_USER_ARGUMENTS:
        assert isinstance(x, int)
        assert isinstance(L, list)
        assert all([isinstance(y, int) for y in L]), \
               "alle elemente i L er ikke heltal"
        assert all([L[i] <= L[i + 1] for i in range(len(L) - 1)]), \
               "L er ikke sorteret"

    # L = [y, y, y, y, y, y, y, y, y, y, y, y, y, y, y]
    #                  ^        ^        ^
    #                 low      mid      high
    #    --- <= x --|                    |------ > x ---

    low = 0
    high = len(L)

    while low < high:
        assert low == 0 or L[low - 1] <= x
        assert high == len(L) or L[high] > x
        
        mid = (low + high) // 2
        if L[mid] <= x:
            assert low < mid + 1
            low = mid + 1
        else:
            assert mid < high 
            high = mid

#    assert 0 <= low and low == high and high <= len(L)   
    assert 0 <= low == high <= len(L)

    result = low

    #if result < 0 or result > len(L):
    #    raise AssertionError
    assert 0 <= result <= len(L)
    assert result == len(L) or x < L[result]
    assert result == 0 or L[result - 1] <= x

    return result


assert rank(11, [3, 5, 8, 10, 12]) == 4
assert rank(8, [3, 5, 8, 10, 12]) == 3
assert rank(-11, [3, 5, 8, 10, 12]) == 0
assert rank(100, [3, 5, 8, 10, 12]) == 5
assert rank(42, []) == 0

# Test many random input lists
for _ in range(1000):
    x = random.randint(-10, 110)
    L = [random.randint(0, 100) for _ in range(100)]
    L.sort()

    assert rank(x, L) == sum([y <= x for y in L])
