{"record":{"id":"b82803fee278feea","repo":"krahets/hello-algo","slug":"error-b82803","errorCode":null,"errorMessage":"куча пуста","messagePattern":"куча пуста","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"ru/codes/python/chapter_heap/my_heap.py","lineNumber":77,"sourceCode":"\n    def sift_up(self, i: int):\n        \"\"\"Начиная с узла i, выполнить просеивание снизу вверх\"\"\"\n        while True:\n            # Получение родительского узла для узла i\n            p = self.parent(i)\n            # Завершить heapify, когда «корневой узел уже пройден» или «узел не требует исправления»\n            if p < 0 or self.max_heap[i] <= self.max_heap[p]:\n                break\n            # Поменять два узла местами\n            self.swap(i, p)\n            # Циклическое просеивание вверх\n            i = p\n\n    def pop(self) -> int:\n        \"\"\"Извлечение элемента из кучи\"\"\"\n        # Обработка пустого случая\n        if self.is_empty():\n            raise IndexError(\"куча пуста\")\n        # Поменять корневой узел с самым правым листом местами (поменять первый и последний элементы)\n        self.swap(0, self.size() - 1)\n        # Удаление узла\n        val = self.max_heap.pop()\n        # Просеивание сверху вниз\n        self.sift_down(0)\n        # Вернуть элемент с вершины кучи\n        return val\n\n    def sift_down(self, i: int):\n        \"\"\"Начиная с узла i, выполнить просеивание сверху вниз\"\"\"\n        while True:\n            # Определить узел с максимальным значением среди i, l и r и обозначить его как ma\n            l, r, ma = self.left(i), self.right(i), i\n            if l < self.size() and self.max_heap[l] > self.max_heap[ma]:\n                ma = l\n            if r < self.size() and self.max_heap[r] > self.max_heap[ma]:\n                ma = r","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/ru/codes/python/chapter_heap/my_heap.py#L59-L95","documentation":"Raised by MaxHeap.pop() in chapter_heap/my_heap.py:77 — IndexError(\"куча пуста\" = \"heap is empty\"). pop() swaps the root with the last leaf, removes the last element, then sifts down to restore the heap property. It refuses to operate on an empty heap because there is no root to extract.","triggerScenarios":"Calling pop() more times than elements were pushed. Calling pop() on a freshly constructed heap. Calling pop() in a draining loop (e.g. heap sort) without an is_empty() termination check.","commonSituations":"See trigger scenarios.","solutions":["Guard: while not heap.is_empty(): heap.pop().","Check heap.size() > 0 before a single pop.","In a sort/drain loop, make is_empty() the loop condition.","Wrap pop() in try/except IndexError for optional extraction."],"exampleFix":"// before\nval = heap.pop()\n// after\nif not heap.is_empty():\n    val = heap.pop()\nelse:\n    val = None","handlingStrategy":"validation","validationCode":"def safe_pop(heap):\n    return heap.pop() if not heap.is_empty() else None","typeGuard":"def heap_has_elements(heap) -> bool:\n    return heap.size() > 0","tryCatchPattern":"try:\n    val = heap.pop()\nexcept IndexError:\n    val = None","preventionTips":["Make is_empty() the drain-loop condition for heap sort","Track push count and never pop more","Seed the heap before any pop"],"tags":["indexerror","heap","precondition","empty-state","python"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}