import math


def string_similarity(string1, string2):
    """
    This implements a "cosine-similarity" algorithm as described for example in
       *Proceedings of the 22nd International Conference on Computation
       Linguistics* (Coling 2008), pages 593-600, Manchester, August 2008.
    The measure-vectors used is simply a "bag of words" type histogram
    (but for letters).

    Args:
        string1 (str): String to compare (may contain any number of words).
        string2 (str): Second string to compare (any number of words).

    Returns:
        similarity (float): A value 0...1 rating how similar the two
            strings are.

    """
    vocabulary = set(list(string1 + string2))
    vec1 = [string1.count(v) for v in vocabulary]
    vec2 = [string2.count(v) for v in vocabulary]
    try:
        return float(sum(vec1[i] * vec2[i] for i in range(len(vocabulary)))) / \
            (math.sqrt(sum(v1**2 for v1 in vec1)) * math.sqrt(sum(v2**2 for v2 in vec2)))
    except ZeroDivisionError:
        # can happen if empty-string cmdnames appear for some reason.
        # This is a no-match.
        return 0