donnemartin/interactive-coding-challenges · error · TypeError

items or total_weight cannot be None

Error message

items or total_weight cannot be None

What it means

Raised by the unbounded-knapsack Knapsack.fill_knapsack when items or total_weight is None. The method immediately computes num_rows = len(items) and num_cols = total_weight + 1, so None inputs are rejected up front with a TypeError instead of raising TypeError from len(None) or TypeError on None + 1.

Source

Thrown at recursion_dynamic/knapsack_unbounded/knapsack_unbounded_solution.ipynb:184

  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Knapsack Bottom Up"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Knapsack(object):\n",
    "\n",
    "    def fill_knapsack(self, items, total_weight):\n",
    "        if items is None or total_weight is None:\n",
    "            raise TypeError('items or total_weight cannot be None')\n",
    "        if not items or total_weight == 0:\n",
    "            return 0\n",
    "        num_rows = len(items)\n",
    "        num_cols = total_weight + 1\n",
    "        T = [0] * (num_cols)\n",
    "        for i in range(num_rows):\n",
    "            for j in range(num_cols):\n",
    "                if j >= items[i].weight:\n",
    "                    T[j] = max(items[i].value + T[j - items[i].weight],\n",
    "                               T[j])\n",
    "        return T[-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Unit Test"

View on GitHub (pinned to 358f2cc604)

Solutions

  1. Pass a list of Item objects and an int capacity, both non-None
  2. Default at the boundary: items = items or [], capacity = capacity or 0
  3. Log and skip the computation when inputs are missing rather than propagating None

Example fix

// before
val = Knapsack().fill_knapsack(items_from_csv, None)
// after
capacity = int(os.getenv('CAPACITY', '0'))
val = Knapsack().fill_knapsack(items_from_csv or [], capacity)
Defensive patterns

Strategy: validation

Validate before calling

items = items or []
total_weight = total_weight if total_weight is not None else 0
Knapsack().fill_knapsack(items, total_weight)

Type guard

def valid_unbounded_args(items, w):
    return isinstance(items, list) and isinstance(w, int) and w >= 0

Try / catch

try:
    Knapsack().fill_knapsack(items, w)
except TypeError as e:
    raise HTTPException(400, str(e)) from e

Prevention

When it happens

Trigger: Calling fill_knapsack(None, 12) or fill_knapsack(items, None). Empty items or total_weight == 0 return 0 and are valid.

Common situations: Reusing the 0/1 knapsack call sites with the unbounded variant where loaders differ; items parsed from CSV rows that can be None; weight capacity sourced from an unset environment/config value.

Related errors


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