donnemartin/interactive-coding-challenges · error · TypeError

a or b cannot be None

Error message

a or b cannot be None

What it means

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.

Source

Thrown at math_probability/sub_two/sub_two_solution.ipynb:106

  },
  {
   "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 integers before calling
  2. Guard at the call site: if a is not None and b is not None: ...
  3. Fix the data structure supplying the operands

Example fix

# before
solution.sub_two(*pair)  # pair = (None, 7) from missing field

# after
if pair[0] is None or pair[1] is None:
    raise ValueError('both operands required')
solution.sub_two(*pair)
Defensive patterns

Strategy: validation

Validate before calling

if a is None or b is None: raise ValueError('a and b are required')
solution.sub_two(a, b)

Type guard

def both_ints(*xs): return all(isinstance(x, int) for x in xs)

Try / catch

try:
    solution.sub_two(a, b)
except TypeError as e:
    # provide defaults or re-raise with context
    raise

Prevention

When it happens

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

Common situations: Tuple-unpacked arguments from data records with missing fields; wrapper functions with a=None, b=None defaults called partially.

Related errors


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