{"record":{"id":"82feeecf1bdaca2b","repo":"krahets/hello-algo","slug":"stack-is-empty-82feee","errorCode":null,"errorMessage":"Stack is empty","messagePattern":"Stack is empty","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"en/codes/python/chapter_stack_and_queue/array_stack.py","lineNumber":30,"sourceCode":"        \"\"\"Constructor\"\"\"\n        self._stack: list[int] = []\n\n    def size(self) -> int:\n        \"\"\"Get the length of the stack\"\"\"\n        return len(self._stack)\n\n    def is_empty(self) -> bool:\n        \"\"\"Check if the stack is empty\"\"\"\n        return self.size() == 0\n\n    def push(self, item: int):\n        \"\"\"Push\"\"\"\n        self._stack.append(item)\n\n    def pop(self) -> int:\n        \"\"\"Pop\"\"\"\n        if self.is_empty():\n            raise IndexError(\"Stack is empty\")\n        return self._stack.pop()\n\n    def peek(self) -> int:\n        \"\"\"Access top of the stack element\"\"\"\n        if self.is_empty():\n            raise IndexError(\"Stack is empty\")\n        return self._stack[-1]\n\n    def to_list(self) -> list[int]:\n        \"\"\"Return list for printing\"\"\"\n        return self._stack\n\n\n\"\"\"Driver Code\"\"\"\nif __name__ == \"__main__\":\n    # Initialize stack\n    stack = ArrayStack()\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/en/codes/python/chapter_stack_and_queue/array_stack.py#L12-L48","documentation":"ArrayStack.pop raises IndexError('Stack is empty') when size() is zero, preventing list.pop() from raising its own opaque IndexError on the empty backing list. The explicit guard gives a domain-meaningful message. It encodes the LIFO contract that you cannot pop what was never pushed.","triggerScenarios":"Calling pop() on a brand-new stack; calling pop() after the last element was popped; unmatched push/pop pairing in expression evaluation or recursion emulation; drain loops that over-pop.","commonSituations":"Bracket/parenthesis matching that pops on every closer; DFS emulation via explicit stack; undo stacks drained past empty; mismatched push/pop counts in parsers.","solutions":["Guard the pop: `if not stack.is_empty(): top = stack.pop()`.","Drive drains with the predicate: `while not stack.is_empty(): x = stack.pop()`.","Use stack.size() to bound counted loops.","Ensure every pop is preceded by a matching push in paired-traversal algorithms."],"exampleFix":"// before\ntop = stack.pop()  # raises if empty\n// after\nif not stack.is_empty():\n    top = stack.pop()\nelse:\n    top = None","handlingStrategy":"validation","validationCode":"if not stack.is_empty():\n    top = stack.pop()","typeGuard":"def stack_nonempty(s) -> bool:\n    return not s.is_empty()","tryCatchPattern":"try:\n    top = stack.pop()\nexcept IndexError:\n    top = None","preventionTips":["Drive drains with `while not stack.is_empty()`.","Match every pop with a prior push in paired-traversal code.","Use size() to bound counted pop loops."],"tags":["stack","indexerror","empty-state","python","data-structures"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}