{"record":{"id":"3e90cee56f8513a4","repo":"TheAlgorithms/Python","slug":"either-arr-or-size-must-be-specified","errorCode":null,"errorMessage":"Either arr or size must be specified","messagePattern":"Either arr or size must be specified","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"data_structures/binary_tree/fenwick_tree.py","lineNumber":26,"sourceCode":"    More info: https://en.wikipedia.org/wiki/Fenwick_tree\n    \"\"\"\n\n    def __init__(self, arr: list[int] | None = None, size: int | None = None) -> None:\n        \"\"\"\n        Constructor for the Fenwick tree\n\n        Parameters:\n            arr (list): list of elements to initialize the tree with (optional)\n            size (int): size of the Fenwick tree (if arr is None)\n        \"\"\"\n\n        if arr is None and size is not None:\n            self.size = size\n            self.tree = [0] * size\n        elif arr is not None:\n            self.init(arr)\n        else:\n            raise ValueError(\"Either arr or size must be specified\")\n\n    def init(self, arr: list[int]) -> None:\n        \"\"\"\n        Initialize the Fenwick tree with arr in O(N)\n\n        Parameters:\n            arr (list): list of elements to initialize the tree with\n\n        Returns:\n            None\n\n        >>> a = [1, 2, 3, 4, 5]\n        >>> f1 = FenwickTree(a)\n        >>> f2 = FenwickTree(size=len(a))\n        >>> for index, value in enumerate(a):\n        ...     f2.add(index, value)\n        >>> f1.tree == f2.tree\n        True","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/data_structures/binary_tree/fenwick_tree.py#L8-L44","documentation":"Raised by FenwickTree.__init__ when neither arr nor size is given. The constructor supports two modes — initialize from an array (self.init(arr)) or allocate an all-zero tree of a given size — and `FenwickTree()` with both arguments None falls into the else branch and raises ValueError. It mirrors the API of competitive-programming Fenwick implementations where an explicit extent is required.","triggerScenarios":"FenwickTree() with no arguments; passing arr=None, size=None explicitly (e.g. forwarding optional kwargs that ended up both None); constructing inside a wrapper whose defaults swallow both parameters.","commonSituations":"Wrapper/config layer that makes both parameters optional; refactoring that renamed arr to values and callers now pass nothing; interactive scripts that skip the size prompt.","solutions":["Pass a size when you plan to add points incrementally: FenwickTree(size=n)","Pass the full array when values are known up front: FenwickTree(arr=values)","In wrappers, give one parameter a real default (e.g. size: int = 10**5) instead of None so both-None cannot reach the constructor"],"exampleFix":"# before\nft = FenwickTree()  # ValueError\n\n# after\nft = FenwickTree(size=n)\n# or\nft = FenwickTree(arr=[0] * n)","handlingStrategy":"validation","validationCode":"if arr is None and size is None:\n    size = 1  # or raise your own descriptive error\nft = FenwickTree(arr=arr, size=size)","typeGuard":null,"tryCatchPattern":"try:\n    ft = FenwickTree(arr, size)\nexcept ValueError:\n    raise ValueError('FenwickTree needs either an array or an explicit size') from None","preventionTips":["Always pass size (for point-update builds) or arr (for bulk init) — never neither","In wrappers, default one parameter to a concrete value rather than None","Watch for renamed kwargs (arr vs values) after refactors"],"tags":["fenwick-tree","bit","constructor","missing-argument"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}