{"record":{"id":"86a70d5382af9f03","repo":"TheAlgorithms/Python","slug":"set-a-and-b-must-either-both-be-sets-or-be-either","errorCode":null,"errorMessage":"Set a and b must either both be sets or be either a list or a tuple.","messagePattern":"Set a and b must either both be sets or be either a list or a tuple\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"maths/jaccard_similarity.py","lineNumber":87,"sourceCode":"        intersection_length = len(set_a.intersection(set_b))\n\n        if alternative_union:\n            union_length = len(set_a) + len(set_b)\n        else:\n            union_length = len(set_a.union(set_b))\n\n        return intersection_length / union_length\n\n    elif isinstance(set_a, (list, tuple)) and isinstance(set_b, (list, tuple)):\n        intersection = [element for element in set_a if element in set_b]\n\n        if alternative_union:\n            return len(intersection) / (len(set_a) + len(set_b))\n        else:\n            # Cast set_a to list because tuples cannot be mutated\n            union = list(set_a) + [element for element in set_b if element not in set_a]\n            return len(intersection) / len(union)\n    raise ValueError(\n        \"Set a and b must either both be sets or be either a list or a tuple.\"\n    )\n\n\nif __name__ == \"__main__\":\n    set_a = {\"a\", \"b\", \"c\", \"d\", \"e\"}\n    set_b = {\"c\", \"d\", \"e\", \"f\", \"h\", \"i\"}\n    print(jaccard_similarity(set_a, set_b))\n","sourceCodeStart":69,"sourceCodeEnd":96,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/maths/jaccard_similarity.py#L69-L96","documentation":"Raised by jaccard_similarity in maths/jaccard_similarity.py when set_a and set_b are not a supported combination. The function handles exactly two cases: both arguments are sets, or both are lists/tuples. Any mixed pairing (set with list) or other types (str, dict, int) falls through to the final raise ValueError at the end of the function. The message summarizes the accepted type combinations.","triggerScenarios":"Calling jaccard_similarity({1,2}, [1,2]) (mixed set and list), jaccard_similarity('abc', 'abd') (strings), or jaccard_similarity({'a':1}, {'b':2}) (dicts). Both arguments must be the same supported kind.","commonSituations":"Datasets where one side came from set() dedup and the other from a JSON list; passing strings expecting character-level comparison; API glue code where the two collections have different provenance.","solutions":["Normalize both sides to the same type before calling: jaccard_similarity(set(a), set(b)).","Wrap strings in lists for token/char comparison: jaccard_similarity(list(s1), list(s2)).","Convert dict comparisons to their key or item views: jaccard_similarity(set(d1), set(d2))."],"exampleFix":"// before\nscore = jaccard_similarity(a, b)  # a is a set, b is a list\n\n// after\nscore = jaccard_similarity(set(a), set(b))","handlingStrategy":"type-guard","validationCode":"a, b = set(a), set(b)  # normalize both sides\nscore = jaccard_similarity(a, b)","typeGuard":"def is_supported_jaccard_pair(a, b) -> bool:\n    both_sets = isinstance(a, set) and isinstance(b, set)\n    both_seqs = isinstance(a, (list, tuple)) and isinstance(b, (list, tuple))\n    return both_sets or both_seqs","tryCatchPattern":"try:\n    s = jaccard_similarity(a, b)\nexcept ValueError:\n    s = jaccard_similarity(set(a), set(b))","preventionTips":["Normalize both collections to the same type before comparing","Wrap strings in list() for character-level similarity"],"tags":["math","similarity","jaccard","type-mismatch","valueerror"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}