donnemartin/interactive-coding-challenges · error · TypeError

a or b cannot be None

Error message

a or b cannot be None

What it means

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.

Source

Thrown at online_judges/sub_two/sub_two_solution.ipynb:110

  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Solution(object):\n",
    "\n",
    "    def sub_two(self, a, b):\n",
    "        if a is None or b is None:\n",
    "            raise TypeError('a or b cannot be None')\n",
    "        result = a ^ b;\n",
    "        borrow = (~a&b) << 1\n",
    "        if borrow != 0:\n",
    "            return self.sub_two(result, borrow)\n",
    "        return result;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Unit Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},

View on GitHub (pinned to 358f2cc604)

Solutions

  1. Ensure both arguments are non-negative Python ints before calling
  2. Convert/validate at the parse site: a = int(a) with error handling rather than falling back to None
  3. Use plain a - b if you do not need the bitwise exercise semantics

Example fix

// before
sol.sub_two(None, 7)
// after
sol.sub_two(10, 7)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(a, int) or not isinstance(b, int):
    raise ValueError('sub_two requires two ints')
sol.sub_two(a, b)

Type guard

def is_nonneg_int(x):
    return isinstance(x, int) and not isinstance(x, bool) and x >= 0

Try / catch

try:
    sol.sub_two(a, b)
except TypeError as e:
    if 'a or b cannot be None' in str(e):
        raise ValueError('operands must be provided') from e
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of donnemartin/interactive-coding-challenges@358f2cc604 (2026-08-28). Data as JSON: /api/errors/c2003c105372d883. Report an issue: GitHub.