{"record":{"id":"88c6b98897775dd8","repo":"donnemartin/interactive-coding-challenges","slug":"a-or-b-cannot-be-none-88c6b9","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":"math_probability/sub_two/sub_two_solution.ipynb","lineNumber":106,"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 sub_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    \"        borrow = (~a & b) << 1\\n\",\n    \"        if borrow != 0:\\n\",\n    \"            return self.sub_two(result, borrow)\\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":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/donnemartin/interactive-coding-challenges/blob/358f2cc60426d5c4c3d7d580910eec9a7b393fa9/math_probability/sub_two/sub_two_solution.ipynb#L88-L124","documentation":"Raised by Solution.sub_two (bitwise subtraction via XOR/borrow recursion) when either a or b is None. The bitwise ops a ^ b and ~a would raise an unhelpful TypeError on None, so both operands are validated first.","triggerScenarios":"Calling sub_two(None, 5), sub_two(5, None), or sub_two(None, None) — usually from unpacking a tuple/list that contains None or forwarding optional parameters.","commonSituations":"Tuple-unpacked arguments from data records with missing fields; wrapper functions with a=None, b=None defaults called partially.","solutions":["Ensure both arguments are integers before calling","Guard at the call site: if a is not None and b is not None: ...","Fix the data structure supplying the operands"],"exampleFix":"# before\nsolution.sub_two(*pair)  # pair = (None, 7) from missing field\n\n# after\nif pair[0] is None or pair[1] is None:\n    raise ValueError('both operands required')\nsolution.sub_two(*pair)","handlingStrategy":"validation","validationCode":"if a is None or b is None: raise ValueError('a and b are required')\nsolution.sub_two(a, b)","typeGuard":"def both_ints(*xs): return all(isinstance(x, int) for x in xs)","tryCatchPattern":"try:\n    solution.sub_two(a, b)\nexcept TypeError as e:\n    # provide defaults or re-raise with context\n    raise","preventionTips":["Avoid unpacking nullable tuples directly into calls","Give wrapper functions real defaults instead of None"],"tags":["python","input-validation","none-check","bit-manipulation","recursion"],"backgroundTag":"none-argument-validation","analyzedSha":"358f2cc60426d5c4c3d7d580910eec9a7b393fa9","analyzedAt":"2026-08-28T10:16:54.480Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}