Computes a modified Levenshtein distance between two strings, comparing the
    lowercase versions of each string and accounting for QWERTY distance.

    Arguments:
        - a (str) String to compare to 'b'
        - b (str) String to compare to 'a'

    Returns:
        - (int) Number representing closeness of 'a' and 'b' (lower is better)

def compute_distance(a, b):
    '''
    Computes a modified Levenshtein distance between two strings, comparing the
    lowercase versions of each string and accounting for QWERTY distance.

    Arguments:
        - a (str) String to compare to 'b'
        - b (str) String to compare to 'a'

    Returns:
        - (int) Number representing closeness of 'a' and 'b' (lower is better)
    '''

    # check simple cases first
    if not a:
        return len(b)
    if not b:
        return len(a)
    if a == b or str.lower(a) == str.lower(b):
        return 0

    # lowercase each string
    a = str.lower(a)
    b = str.lower(b)

    # create empty vectors to store costs
    vector_1 = [-1] * (len(b) + 1)
    vector_2 = [-1] * (len(b) + 1)

    # set default values
    for i in range(len(vector_1)):
        vector_1[i] = i

    # compute distance
    for i in range(len(a)):
        vector_2[0] = i + 1

        for j in range(len(b)):
            penalty = 0 if a[i] == b[j] else compute_qwerty_distance(a[i], b[j])
            vector_2[j + 1] = min(vector_2[j] + 1, vector_1[j + 1] + 1, vector_1[j] + penalty)

        for j in range(len(vector_1)):
            vector_1[j] = vector_2[j]

    return vector_2[len(b)]