{"record":{"id":"c2003c105372d883","repo":"donnemartin/interactive-coding-challenges","slug":"a-or-b-cannot-be-none-c2003c","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/sub_two/sub_two_solution.ipynb","lineNumber":110,"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":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/donnemartin/interactive-coding-challenges/blob/358f2cc60426d5c4c3d7d580910eec9a7b393fa9/online_judges/sub_two/sub_two_solution.ipynb#L92-L128","documentation":"sub_two implements subtraction with bitwise operators (XOR plus a shifted borrow term, recursing until borrow is 0) and raises TypeError if a or b is None. Because the recursion feeds computed ints back in, the guard mainly protects the public entry point against non-int input. None operands would crash the ^ operation with a vaguer error, so the check makes the contract explicit.","triggerScenarios":"Calling Solution().sub_two(None, 5) or sub_two(5, None); passing values parsed from text (e.g. int(x) that failed and left the variable None) instead of ints.","commonSituations":"Parsing numeric inputs where conversion failure sets None; mixed-sign expectations — note this bitwise trick works cleanly only for non-negative ints in Python's unbounded-int world; test fixtures that include None.","solutions":["Ensure both arguments are non-negative Python ints before calling","Convert/validate at the parse site: a = int(a) with error handling rather than falling back to None","Use plain a - b if you do not need the bitwise exercise semantics"],"exampleFix":"// before\nsol.sub_two(None, 7)\n// after\nsol.sub_two(10, 7)","handlingStrategy":"type-guard","validationCode":"if not isinstance(a, int) or not isinstance(b, int):\n    raise ValueError('sub_two requires two ints')\nsol.sub_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.sub_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":["Convert parsed numeric text with int() and handle failure explicitly","Keep bitwise-arithmetic helpers restricted to non-negative ints","Prefer native '-' in production code"],"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"}