donnemartin/interactive-coding-challenges · error · TypeError

input_items or total_weight cannot be None

Error message

input_items or total_weight cannot be None

What it means

Raised by Knapsack.fill_knapsack (bottom-up 0/1 knapsack) when input_items or total_weight is None. The dynamic-programming table construction immediately indexes items and uses total_weight as a column count, so None inputs are rejected up front with a TypeError rather than crashing inside the table loop.

Source

Thrown at recursion_dynamic/knapsack_01/knapsack_solution.ipynb:166

  },
  {
   "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, input_items, total_weight):\n",
    "        if input_items is None or total_weight is None:\n",
    "            raise TypeError('input_items or total_weight cannot be None')\n",
    "        if not input_items or total_weight == 0:\n",
    "            return 0\n",
    "        items = list([Item(label='', value=0, weight=0)] + input_items)\n",
    "        num_rows = len(items)\n",
    "        num_cols = total_weight + 1\n",
    "        T = [[None] * num_cols for _ in range(num_rows)]\n",
    "        for i in range(num_rows):\n",
    "            for j in range(num_cols):\n",
    "                if i == 0 or j == 0:\n",
    "                    T[i][j] = 0\n",
    "                elif j >= items[i].weight:\n",
    "                    T[i][j] = max(items[i].value + T[i - 1][j - items[i].weight],\n",
    "                                  T[i - 1][j])\n",
    "                else:\n",
    "                    T[i][j] = T[i - 1][j]\n",
    "        results = []\n",
    "        i = num_rows - 1\n",
    "        j = num_cols - 1\n",

View on GitHub (pinned to 358f2cc604)

Solutions

  1. Pass a real list of Item objects (even [] is fine and returns 0) and an integer total_weight
  2. Default optional values: items = items or [] and weight = 0 if weight is None
  3. Validate parsed input before constructing the Knapsack call

Example fix

// before
ks.fill_knapsack(None, total_weight=10)
// after
items = items if items is not None else []
ks.fill_knapsack(items, 10)
Defensive patterns

Strategy: type-guard

Validate before calling

assert input_items is not None and total_weight is not None
ks.fill_knapsack(input_items, total_weight)

Type guard

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

Try / catch

try:
    value = ks.fill_knapsack(items, w)
except TypeError:
    value = 0  # treat as empty instance

Prevention

When it happens

Trigger: Calling fill_knapsack(None, 10) or fill_knapsack(items, None). Note the next line treats an empty list or total_weight == 0 as a valid 0-return case, so only None triggers the raise.

Common situations: Loading item lists from JSON/datasets where the items key is missing; passing an uninitialized weight; wiring the call to optional config values that default to None.

Related errors


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