donnemartin/interactive-coding-challenges · error · ValueError

Index cannot be negative

Error message

Index cannot be negative

What it means

Bits.insert_m_into_n raises ValueError('Index cannot be negative') when i or j is negative. These define the inclusive bit window [i, j] in n that m is inserted into; negative positions have no meaning for the mask arithmetic (left_mask = -1 << (j+1), right_mask = (1 << i) - 1).

Source

Thrown at bit_manipulation/insert_m_into_n/insert_m_into_n_solution.ipynb:120

   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Bits(object):\n",
    "\n",
    "    def insert_m_into_n(self, m, n, i, j):\n",
    "        if None in (m, n, i, j):\n",
    "            raise TypeError('Argument cannot be None')\n",
    "        if i < 0 or j < 0:\n",
    "            raise ValueError('Index cannot be negative')\n",
    "        left_mask = -1 << (j + 1)\n",
    "        right_mask = (1 << i) - 1\n",
    "        n_mask = left_mask | right_mask\n",
    "        # Clear bits from j to i, inclusive\n",
    "        n_cleared = n & n_mask\n",
    "        # Shift m into place before inserting it into n\n",
    "        m_mask = m << i\n",
    "        return n_cleared | m_mask"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Unit Test"
   ]
  },
  {

View on GitHub (pinned to 358f2cc604)

Solutions

  1. Clamp: i = max(i, 0) and j = max(j, i) when a degenerate window is acceptable
  2. Validate 0 <= i <= j before calling and reject bad specs with your own error
  3. Fix the arithmetic producing the negative bound

Example fix

# before
bits.insert_m_into_n(m, n, start - 2, end)

# after
i = max(start - 2, 0)
bits.insert_m_into_n(m, n, i, end)
Defensive patterns

Strategy: validation

Validate before calling

if i < 0 or j < 0:
    raise ValueError(f'i and j must be non-negative, got i={i}, j={j}')
bits.insert_m_into_n(m, n, i, j)

Type guard

def valid_window(i, j) -> bool:
    return isinstance(i, int) and isinstance(j, int) and 0 <= i <= j

Try / catch

try:
    result = bits.insert_m_into_n(m, n, i, j)
except ValueError as e:
    if 'negative' in str(e):
        i, j = abs(i), abs(j)
        result = bits.insert_m_into_n(m, n, i, j)
    else:
        raise

Prevention

When it happens

Trigger: insert_m_into_n(2, 15, -1, 3) or insert_m_into_n(2, 15, 2, -3); also i, j computed from a subtraction like j = end - start that went negative.

Common situations: Window bounds derived from lengths or offsets that underflow; sign errors when parsing index specs from user input or JSON.

Related errors


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