{"record":{"id":"8420128da34542f4","repo":"donnemartin/interactive-coding-challenges","slug":"a-or-b-cannot-be-none-842012","errorCode":null,"errorMessage":"a or b cannot be None","messagePattern":"a or b cannot be None","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"online_judges/sum_two/sum_two_solution.ipynb","lineNumber":126,"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 sum_two(self, a, b):\\n\",\n    \"        if a is None or b is None:\\n\",\n    \"            raise TypeError('a or b cannot be None')\\n\",\n    \"        result = a ^ b;\\n\",\n    \"        carry = (a&b) << 1\\n\",\n    \"        if carry != 0:\\n\",\n    \"            return self.sum_two(result, carry)\\n\",\n    \"        return result;\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/donnemartin/interactive-coding-challenges/blob/358f2cc60426d5c4c3d7d580910eec9a7b393fa9/online_judges/sum_two/sum_two_solution.ipynb#L108-L144","documentation":"sum_two implements addition with bitwise operators (XOR plus shifted carry, recursing until carry is 0) and raises TypeError when a or b is None. The guard protects the public API since the internal recursion always passes ints. Without it, a ^ b on None would raise a confusing TypeError about unsupported operand types.","triggerScenarios":"Calling Solution().sum_two(None, 3) or sum_two(3, None); forwarding optional numeric params (e.g. defaults of None) directly into the method.","commonSituations":"Optional fields in deserialized data left as None and passed through; misreading the API as accepting nullable numbers; notebook cells referencing unassigned variables. Beware also that with negative ints this carry loop can recurse very long in Python (no fixed-width wrap).","solutions":["Pass non-negative ints, converting explicitly beforehand","Resolve None-defaults at the call site: b = b if b is not None else 0","Replace with a + b for production use; the bitwise version is an interview exercise"],"exampleFix":"// before\ndef add(x, y=None):\n    return sol.sum_two(x, y)\n// after\ndef add(x, y=0):\n    return sol.sum_two(x, y)","handlingStrategy":"type-guard","validationCode":"a = a if a is not None else 0\nb = b if b is not None else 0\nsol.sum_two(a, b)","typeGuard":"def is_nonneg_int(x):\n    return isinstance(x, int) and not isinstance(x, bool) and x >= 0","tryCatchPattern":"try:\n    sol.sum_two(a, b)\nexcept TypeError as e:\n    if 'a or b cannot be None' in str(e):\n        raise ValueError('operands must be provided') from e\n    raise","preventionTips":["Use 0 defaults for numeric optional params","Validate deserialized numeric fields before calling","Avoid negative operands with the bitwise carry loop; use '+' instead"],"tags":["python","input-validation","typeerror","bit-manipulation","recursion"],"backgroundTag":"none-argument-typeerror","analyzedSha":"358f2cc60426d5c4c3d7d580910eec9a7b393fa9","analyzedAt":"2026-08-28T10:16:54.480Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}