{"record":{"id":"f73f3b45f8a3e047","repo":"donnemartin/interactive-coding-challenges","slug":"s-or-t-cannot-be-none","errorCode":null,"errorMessage":"s or t cannot be None","messagePattern":"s or t cannot be None","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"online_judges/str_diff/str_diff_solution.ipynb","lineNumber":90,"sourceCode":"  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def find_diff(self, s, t):\\n\",\n    \"        if s is None or t is None:\\n\",\n    \"            raise TypeError('s or t cannot be None')\\n\",\n    \"        seen = {}\\n\",\n    \"        for char in s:\\n\",\n    \"            if char in seen:\\n\",\n    \"                seen[char] += 1\\n\",\n    \"            else:\\n\",\n    \"                seen[char] = 1\\n\",\n    \"        for char in t:\\n\",\n    \"            try:\\n\",\n    \"                seen[char] -= 1\\n\",\n    \"            except KeyError:\\n\",\n    \"                return char\\n\",\n    \"            if seen[char] < 0:\\n\",\n    \"                return char\\n\",\n    \"        return None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/donnemartin/interactive-coding-challenges/blob/358f2cc60426d5c4c3d7d580910eec9a7b393fa9/online_judges/str_diff/str_diff_solution.ipynb#L72-L108","documentation":"find_diff (find the difference between two strings where t is a permutation of s plus one extra char) raises TypeError when either s or t is None. The counting-dict logic iterates both strings, so None would fail with a less clear error; the guard fails fast with an explicit message. The algorithm itself assumes both inputs are strings of the same alphabet.","triggerScenarios":"Calling Solution().find_diff(None, 'abc') or find_diff('abc', None) or both None; passing t loaded from a file/stream that hit EOF and returned None.","commonSituations":"String pairs read from paired files or API fields where one side is missing; notebook variables not yet assigned before the cell runs; optional request parameters forwarded without defaults.","solutions":["Pass both strings, using '' for the legitimately empty case","Default missing inputs to empty strings at the boundary: s = s or ''","Add tests covering the None contract so callers know it is intentionally rejected"],"exampleFix":"// before\nsol.find_diff(s, t)  # t is None\n// after\nsol.find_diff(s if s is not None else '', t if t is not None else '')","handlingStrategy":"validation","validationCode":"s = s or ''\nt = t or ''\nsol.find_diff(s, t)","typeGuard":"def is_str(x):\n    return isinstance(x, str)","tryCatchPattern":"try:\n    sol.find_diff(s, t)\nexcept TypeError as e:\n    if 's or t cannot be None' in str(e):\n        raise ValueError('both strings are required') from e\n    raise","preventionTips":["Default optional string params to '' rather than None","Check paired file/stream reads both succeeded","Guard deserialized fields before algorithm calls"],"tags":["python","input-validation","typeerror","strings"],"backgroundTag":"none-argument-typeerror","analyzedSha":"358f2cc60426d5c4c3d7d580910eec9a7b393fa9","analyzedAt":"2026-08-28T10:16:54.480Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}