{"record":{"id":"e67077e7d50f0268","repo":"krahets/hello-algo","slug":"error-e67077","errorCode":null,"errorMessage":"両端キューが空です","messagePattern":"両端キューが空です","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"ja/codes/python/chapter_stack_and_queue/array_deque.py","lineNumber":76,"sourceCode":"\n    def pop_first(self) -> int:\n        \"\"\"キュー先頭からデキュー\"\"\"\n        num = self.peek_first()\n        # 先頭ポインタを 1 つ後ろへ進める\n        self._front = self.index(self._front + 1)\n        self._size -= 1\n        return num\n\n    def pop_last(self) -> int:\n        \"\"\"キュー末尾からデキュー\"\"\"\n        num = self.peek_last()\n        self._size -= 1\n        return num\n\n    def peek_first(self) -> int:\n        \"\"\"キュー先頭の要素にアクセス\"\"\"\n        if self.is_empty():\n            raise IndexError(\"両端キューが空です\")\n        return self._nums[self._front]\n\n    def peek_last(self) -> int:\n        \"\"\"キュー末尾の要素にアクセス\"\"\"\n        if self.is_empty():\n            raise IndexError(\"両端キューが空です\")\n        # 末尾要素のインデックスを計算\n        last = self.index(self._front + self._size - 1)\n        return self._nums[last]\n\n    def to_array(self) -> list[int]:\n        \"\"\"出力用の配列を返す\"\"\"\n        # 有効長の範囲内のリスト要素のみを変換\n        res = []\n        for i in range(self._size):\n            res.append(self._nums[self.index(self._front + i)])\n        return res\n","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/ja/codes/python/chapter_stack_and_queue/array_deque.py#L58-L94","documentation":"This IndexError (Japanese: '両端キューが空です' = 'deque is empty') is raised by ArrayDeque.peek_first() (array_deque.py:76) when the deque holds no elements. peek_first reads _nums[_front], which is meaningless when _size == 0. ArrayDeque is a fixed-capacity circular-array deque. Note pop_first() calls peek_first() internally, so the same exception propagates through pop_first() too.","triggerScenarios":"Calling peek_first() on a freshly constructed ArrayDeque (size 0). Calling peek_first() / pop_first() after draining all elements. Note: the capacity-full case is handled differently here — push_first only prints a warning and returns, it does NOT raise, so 'empty' is the only IndexError from peek/pop.","commonSituations":"Peeking before any push. Draining with repeated pop_first() and then peeking. Assuming the deque is non-empty after a push that silently failed because capacity was full (push_first prints but does not raise on full).","solutions":["Check `if not dq.is_empty(): dq.peek_first()`.","When draining, loop on `while not dq.is_empty():`.","Be aware push_first/push_last silently no-op when full (they print, not raise) — verify size after pushes if you depend on the element being present.","Pair every peek/pop with a size() or is_empty() guard in calling code."],"exampleFix":"// before\nfirst = dq.peek_first()  # IndexError on empty\n\n// after\nfirst = dq.peek_first() if not dq.is_empty() else None","handlingStrategy":"validation","validationCode":"if not dq.is_empty():\n    first = dq.peek_first()\n# remember: push_first silently no-ops (prints) when full — verify size after push","typeGuard":"def deque_has_first(dq: ArrayDeque) -> bool:\n    return not dq.is_empty()","tryCatchPattern":"try:\n    first = dq.peek_first()\nexcept IndexError:\n    first = None","preventionTips":["Check is_empty() before peek_first() or pop_first() (pop delegates to peek).","Note push_first/push_last only print on full — confirm size() changed if you depend on the element.","Drain with `while not dq.is_empty():`.","Never assume capacity implies occupancy."],"tags":["deque","python","index-error","empty","circular-array"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}