donnemartin/interactive-coding-challenges · error · TypeError

num cannot be None

Error message

num cannot be None

What it means

Solution.add_digits raises TypeError('num cannot be None') because the digit-extraction loop (num % 10, num //= 10) requires an integer. The guard rejects None input before any arithmetic is attempted, keeping the failure message clear rather than a confusing TypeError about unsupported operand types.

Source

Thrown at math_probability/add_digits/add_digits_solution.ipynb:99

  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Solution(object):\n",
    "\n",
    "    def add_digits(self, num):\n",
    "        if num is None:\n",
    "            raise TypeError('num cannot be None')\n",
    "        if num < 0:\n",
    "            raise ValueError('num cannot be negative')\n",
    "        digits = []\n",
    "        while num != 0:\n",
    "            digits.append(num % 10)\n",
    "            num //= 10\n",
    "        digits_sum = sum(digits)\n",
    "        if digits_sum >= 10:\n",
    "            return self.add_digits(digits_sum)\n",
    "        else:\n",
    "            return digits_sum\n",
    "\n",
    "    def add_digits_optimized(self, num):\n",
    "        if num is None:\n",
    "            raise TypeError('num cannot be None')\n",
    "        if num < 0:\n",
    "            raise ValueError('num cannot be negative')\n",
    "        if num == 0:\n",

View on GitHub (pinned to 358f2cc604)

Solutions

  1. Validate and coerce input before the call: num = int(num) if num is not None else fail early
  2. Check the data source producing None (missing field, failed parse)
  3. Catch TypeError when None is a legitimate edge case in tests

Example fix

// before
result = solution.add_digits(value)  # TypeError if value is None
// after
if value is None:
    raise ValueError('missing numeric input')
result = solution.add_digits(int(value))
Defensive patterns

Strategy: validation

Validate before calling

if num is None or not isinstance(num, int):
    raise ValueError('num must be an integer')
solution.add_digits(num)

Type guard

def is_int(num) -> bool:
    return isinstance(num, int) and num is not None

Try / catch

try:
    result = solution.add_digits(num)
except TypeError:
    result = None

Prevention

When it happens

Trigger: Calling add_digits(None), or passing a parsed value (str.isdigit-unchecked input, optional config field) that resolved to None.

Common situations: Processing unvalidated user or file input where a missing numeric field becomes None; test suites that include None as an edge case alongside negative and zero values.

Related errors


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