donnemartin/interactive-coding-challenges · error · Exception

Stack is empty

Error message

Stack is empty

What it means

n_stacks' pop raises Exception('Stack is empty') when the stack pointer for that stack_index is -1, meaning no elements have been pushed (or all were popped) on that virtual stack. It prevents reading uninitialized slots of the backing array.

Solutions

  1. Track or check emptiness before popping: peek at stack_pointers[stack_index] == -1
  2. Ensure every pop has a corresponding successful push for the same stack_index
  3. Wrap pop in try/except Exception and treat underflow as a no-op or signal if unavoidable

Example fix

# before
data = stacks.pop(0)  # may raise 'Stack is empty'

# after
if stacks.stack_pointers[0] != -1:
    data = stacks.pop(0)
else:
    data = None
Defensive patterns

Strategy: validation

Validate before calling

if stacks.stack_pointers[stack_index] != -1:
    data = stacks.pop(stack_index)
else:
    data = None

Try / catch

try:
    data = stacks.pop(i)
except Exception as e:
    if str(e) == 'Stack is empty':
        data = None  # treat underflow as empty
    else:
        raise

Prevention

When it happens

Trigger: Calling pop(stack_index) on a freshly created stack, or popping more times than you pushed on that same stack_index. Each of the N stacks tracks underflow independently.

Common situations: Mismatched push/pop pairing across code paths; popping in a loop without checking remaining elements; mixing up stack indices so you pop a stack you never pushed to.

Related errors


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

Appendix: source

Thrown at stacks_queues/n_stacks/n_stacks_solution.ipynb:136

    "    def __init__(self, num_stacks, stack_size):\n",
    "        self.num_stacks = num_stacks\n",
    "        self.stack_size = stack_size\n",
    "        self.stack_pointers = [-1] * self.num_stacks\n",
    "        self.stack_array = [None] * self.num_stacks * self.stack_size\n",
    "\n",
    "    def abs_index(self, stack_index):\n",
    "        return stack_index * self.stack_size + self.stack_pointers[stack_index]\n",
    "\n",
    "    def push(self, stack_index, data):\n",
    "        if self.stack_pointers[stack_index] == self.stack_size - 1:\n",
    "            raise Exception('Stack is full')\n",
    "        self.stack_pointers[stack_index] += 1\n",
    "        array_index = self.abs_index(stack_index)\n",
    "        self.stack_array[array_index] = data\n",
    "\n",
    "    def pop(self, stack_index):\n",
    "        if self.stack_pointers[stack_index] == -1:\n",
    "            raise Exception('Stack is empty')\n",
    "        array_index = self.abs_index(stack_index)\n",
    "        data = self.stack_array[array_index]\n",
    "        self.stack_array[array_index] = None\n",
    "        self.stack_pointers[stack_index] -= 1\n",
    "        return data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Unit Test\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,

View on GitHub (pinned to 358f2cc604)