We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Histogram protocol issue?
I am confused about `PlottableAxisContinuous.__getitem__`: for uproot4 it seems to give the one-indexed values where I was expecting zero-indexed, since `__len__` gives the number of bins without flow. For example:
```
>>> h = uproot.open('https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples/testSF2d.histo.root:scalefactors_Tight_Electron')
>>> axis = h.axes[0]
>>> len(axis)
10
>>> axis.edges()
array([-2.5  , -2.   , -1.566, -1.444, -0.8  ,  0.   ,  0.8  ,  1.444,
        1.566,  2.   ,  2.5  ])
>>> axis.edges().shape
(11,)
>>> axis[0]
(-2.0, -1.566)
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `uproot/behaviors/TAxis.py`
Content:
```
1 # BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/main/LICENSE
2 
3 """
4 This module defines the behaviors of ``TAxis``, an axis of a histogram or profile plot.
5 """
6 
7 from __future__ import absolute_import
8 
9 try:
10     from collections.abc import Sequence
11 except ImportError:
12     from collections import Sequence
13 
14 import numpy
15 
16 
17 class AxisTraits(object):
18     """
19     Describes read-only properties of a histogram axis.
20 
21     For example, ``axis.traits.discrete`` is True if the histogram has
22     labels; False otherwise.
23     """
24 
25     def __init__(self, axis):
26         self._axis = axis
27 
28     def __repr__(self):
29         return "AxisTraits({0})".format(repr(self._axis))
30 
31     @property
32     def circular(self):
33         """
34         True if the axis "wraps around" (always False for ROOT histograms).
35         """
36         return False
37 
38     @property
39     def discrete(self):
40         """
41         True if bins are discrete: if they have string-valued labels.
42         """
43         fNbins = self._axis.member("fNbins")
44         fLabels = self._axis.member("fLabels", none_if_missing=True)
45         return fLabels is not None and len(fLabels) == fNbins
46 
47 
48 class TAxis(Sequence):
49     def __len__(self):
50         """
51         The number of bins in the axis.
52         """
53         return self.member("fNbins")
54 
55     def __getitem__(self, where):
56         """
57         Returns the label at ``where`` if it exists or the interval at ``where``.
58 
59         The indexing assumes that ``flow=False``.
60         """
61         fNbins = self.member("fNbins")
62         fXbins = self.member("fXbins", none_if_missing=True)
63         fLabels = self.member("fLabels", none_if_missing=True)
64 
65         if fLabels is not None and len(fLabels) == fNbins:
66             return str(fLabels[where])
67 
68         elif fXbins is None or len(fXbins) != fNbins + 1:
69             fXmin, fXmax = self.member("fXmin"), self.member("fXmax")
70             low = (fXmax - fXmin) * (where) / float(fNbins) + fXmin
71             high = (fXmax - fXmin) * (where + 1) / float(fNbins) + fXmin
72             return low, high
73 
74         else:
75             return fXbins[where + 1], fXbins[where + 2]
76 
77     def __iter__(self):
78         """
79         Iterate over the output of ``__getitem__``.
80         """
81         fNbins = self.member("fNbins")
82         fLabels = self.member("fLabels", none_if_missing=True)
83 
84         if fLabels is not None and len(fLabels) == fNbins:
85             for x in fLabels:
86                 yield str(x)
87         else:
88             for low, high in self.intervals():
89                 yield low, high
90 
91     def __eq__(self, other):
92         """
93         Two axes are equal if they have the same type and
94         ``list(self) == list(other)``.
95         """
96         if type(self) is not type(other):
97             return False
98 
99         self_fNbins = self.member("fNbins")
100         other_fNbins = other.member("fNbins")
101         if self_fNbins != other_fNbins:
102             return False
103 
104         self_fLabels = self.member("fLabels", none_if_missing=True)
105         other_fLabels = other.member("fLabels", none_if_missing=True)
106         self_labeled = self_fLabels is not None and len(self_fLabels) == self_fNbins
107         other_labeled = other_fLabels is not None and len(other_fLabels) == other_fNbins
108 
109         if self_labeled and other_labeled:
110             return all(x == y for x, y in zip(self_fLabels, other_fLabels))
111         elif not self_labeled and not other_labeled:
112             return numpy.array_equal(self.edges(), other.edges())
113         else:
114             return False
115 
116     def __ne__(self, other):
117         """
118         Some versions of Python don't automatically negate __eq__.
119         """
120         return not self.__eq__(other)
121 
122     @property
123     def traits(self):
124         """
125         Describes read-only properties of a histogram axis.
126 
127         For example, ``axis.traits.discrete`` is True if the histogram has
128         labels; False otherwise.
129         """
130         return AxisTraits(self)
131 
132     @property
133     def low(self):
134         """
135         The low edge of the first normal (finite-width) bin.
136 
137         For ROOT histograms, numerical edges exist even if the axis also has
138         string-valued labels.
139         """
140         return self.member("fXmin")
141 
142     @property
143     def high(self):
144         """
145         The high edge of the last normal (finite-width) bin.
146 
147         For ROOT histograms, numerical edges exist even if the axis also has
148         string-valued labels.
149         """
150         return self.member("fXmax")
151 
152     @property
153     def width(self):
154         """
155         The average bin width (or only bin width if the binning is uniform).
156         """
157         fNbins = self.member("fNbins")
158         fXbins = self.member("fXbins", none_if_missing=True)
159 
160         if fXbins is None or len(fXbins) != fNbins + 1:
161             return (self.member("fXmax") - self.member("fXmin")) / fNbins
162         else:
163             return self.widths().mean()
164 
165     def labels(self, flow=False):
166         """
167         Args:
168             flow (bool): If True, include ``"underflow"`` and ``"overflow"``
169                 before and after the normal (finite-width) bin labels (if they
170                 exist).
171 
172         If string-valued labels exist, this returns them as a Python list of
173         Python strings. Otherwise, this returns None.
174 
175         Setting ``flow=True`` increases the length of the output by two.
176         """
177         fNbins = self.member("fNbins")
178         fLabels = self.member("fLabels", none_if_missing=True)
179 
180         if fLabels is not None and len(fLabels) == fNbins:
181             out = [str(x) for x in fLabels]
182             if flow:
183                 return ["underflow"] + out + ["overflow"]
184             else:
185                 return out
186         else:
187             return None
188 
189     def edges(self, flow=False):
190         """
191         Args:
192             flow (bool): If True, include ``-inf`` and ``inf`` before and
193                 after the normal (finite-width) bin edges.
194 
195         Returns numerical edges between bins as a one-dimensional ``numpy.ndarray``
196         of ``numpy.float64``.
197 
198         Even with ``flow=False``, the number of edges is *one greater than* the
199         number of normal (finite-width) bins because they represent "fenceposts"
200         between the bins, including one below and one above the full range.
201 
202         Setting ``flow=True`` increases the length of the output by two.
203 
204         For ROOT histograms, numerical edges exist even if the axis also has
205         string-valued labels.
206         """
207         fNbins = self.member("fNbins")
208         fXbins = self.member("fXbins", none_if_missing=True)
209 
210         if fXbins is None or len(fXbins) != fNbins + 1:
211             fXbins = numpy.linspace(
212                 self.member("fXmin"), self.member("fXmax"), fNbins + 1
213             )
214 
215         if flow:
216             out = numpy.empty(fNbins + 3, dtype=numpy.float64)
217             out[0] = -numpy.inf
218             out[-1] = numpy.inf
219             out[1:-1] = fXbins
220         else:
221             out = numpy.asarray(fXbins, dtype=fXbins.dtype.newbyteorder("="))
222 
223         return out
224 
225     def intervals(self, flow=False):
226         """
227         Args:
228             flow (bool): If True, include ``[-inf, min]`` and ``[max, inf]``
229                 before and after the normal (finite-width) intervals.
230 
231         Returns low, high pairs for each bin interval as a two-dimensional
232         ``numpy.ndarray`` of ``numpy.float64``.
233 
234         With ``flow=False``, the number of intervals is equal to the number of
235         normal (finite-width) bins.
236 
237         Setting ``flow=True`` increases the length of the output by two.
238 
239         For ROOT histograms, numerical intervals exist even if the axis also has
240         string-valued labels.
241         """
242         fNbins = self.member("fNbins")
243         fXbins = self.member("fXbins", none_if_missing=True)
244 
245         if fXbins is None or len(fXbins) != fNbins + 1:
246             fXbins = numpy.linspace(
247                 self.member("fXmin"), self.member("fXmax"), fNbins + 1
248             )
249 
250         if flow:
251             out = numpy.empty((fNbins + 2, 2), dtype=numpy.float64)
252             out[0, 0] = -numpy.inf
253             out[-1, 1] = numpy.inf
254             out[1:, 0] = fXbins
255             out[:-1, 1] = fXbins
256         else:
257             out = numpy.empty((fNbins, 2), dtype=numpy.float64)
258             out[:, 0] = fXbins[:-1]
259             out[:, 1] = fXbins[1:]
260 
261         return out
262 
263     def centers(self, flow=False):
264         """
265         Args:
266             flow (bool): If True, include ``-inf`` and ``inf`` before and after
267                 the normal (finite) bin centers.
268 
269         Returns bin center positions as a one-dimensional ``numpy.ndarray`` of
270         ``numpy.float64``.
271 
272         With ``flow=False``, the number of bin centers is equal to the number of
273         normal (finite-width) bins.
274 
275         Setting ``flow=True`` increases the length of the output by two.
276 
277         For ROOT histograms, numerical bin centers exist even if the axis also has
278         string-valued labels.
279         """
280         edges = self.edges(flow=flow)
281         return (edges[1:] + edges[:-1]) / 2.0
282 
283     def widths(self, flow=False):
284         """
285         Args:
286             flow (bool): If True, include ``-inf`` and ``inf`` before and after
287                 the normal (finite) bin widths.
288 
289         Returns bin widths as a one-dimensional ``numpy.ndarray`` of
290         ``numpy.float64``.
291 
292         With ``flow=False``, the number of bin widths is equal to the number of
293         normal (finite-width) bins.
294 
295         Setting ``flow=True`` increases the length of the output by two.
296 
297         For ROOT histograms, numerical bin widths exist even if the axis also has
298         string-valued labels.
299         """
300         fNbins = self.member("fNbins")
301         fXbins = self.member("fXbins", none_if_missing=True)
302 
303         if not flow and (fXbins is None or len(fXbins) != fNbins + 1):
304             width = (self.member("fXmax") - self.member("fXmin")) / fNbins
305             return numpy.broadcast_to(width, (fNbins,))
306         else:
307             edges = self.edges(flow=flow)
308             return edges[1:] - edges[:-1]
309
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/uproot/behaviors/TAxis.py b/uproot/behaviors/TAxis.py
--- a/uproot/behaviors/TAxis.py
+++ b/uproot/behaviors/TAxis.py
@@ -72,7 +72,7 @@
             return low, high
 
         else:
-            return fXbins[where + 1], fXbins[where + 2]
+            return fXbins[where], fXbins[where + 1]
 
     def __iter__(self):
         """

{"golden_diff": "diff --git a/uproot/behaviors/TAxis.py b/uproot/behaviors/TAxis.py\n--- a/uproot/behaviors/TAxis.py\n+++ b/uproot/behaviors/TAxis.py\n@@ -72,7 +72,7 @@\n             return low, high\n \n         else:\n-            return fXbins[where + 1], fXbins[where + 2]\n+            return fXbins[where], fXbins[where + 1]\n \n     def __iter__(self):\n         \"\"\"\n", "issue": "Histogram protocol issue?\nI am confused about `PlottableAxisContinuous.__getitem__`: for uproot4 it seems to give the one-indexed values where I was expecting zero-indexed, since `__len__` gives the number of bins without flow. For example:\r\n```\r\n>>> h = uproot.open('https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples/testSF2d.histo.root:scalefactors_Tight_Electron')\r\n>>> axis = h.axes[0]\r\n>>> len(axis)\r\n10\r\n>>> axis.edges()\r\narray([-2.5  , -2.   , -1.566, -1.444, -0.8  ,  0.   ,  0.8  ,  1.444,\r\n        1.566,  2.   ,  2.5  ])\r\n>>> axis.edges().shape\r\n(11,)\r\n>>> axis[0]\r\n(-2.0, -1.566)\r\n```\n", "before_files": [{"content": "# BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/main/LICENSE\n\n\"\"\"\nThis module defines the behaviors of ``TAxis``, an axis of a histogram or profile plot.\n\"\"\"\n\nfrom __future__ import absolute_import\n\ntry:\n    from collections.abc import Sequence\nexcept ImportError:\n    from collections import Sequence\n\nimport numpy\n\n\nclass AxisTraits(object):\n    \"\"\"\n    Describes read-only properties of a histogram axis.\n\n    For example, ``axis.traits.discrete`` is True if the histogram has\n    labels; False otherwise.\n    \"\"\"\n\n    def __init__(self, axis):\n        self._axis = axis\n\n    def __repr__(self):\n        return \"AxisTraits({0})\".format(repr(self._axis))\n\n    @property\n    def circular(self):\n        \"\"\"\n        True if the axis \"wraps around\" (always False for ROOT histograms).\n        \"\"\"\n        return False\n\n    @property\n    def discrete(self):\n        \"\"\"\n        True if bins are discrete: if they have string-valued labels.\n        \"\"\"\n        fNbins = self._axis.member(\"fNbins\")\n        fLabels = self._axis.member(\"fLabels\", none_if_missing=True)\n        return fLabels is not None and len(fLabels) == fNbins\n\n\nclass TAxis(Sequence):\n    def __len__(self):\n        \"\"\"\n        The number of bins in the axis.\n        \"\"\"\n        return self.member(\"fNbins\")\n\n    def __getitem__(self, where):\n        \"\"\"\n        Returns the label at ``where`` if it exists or the interval at ``where``.\n\n        The indexing assumes that ``flow=False``.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fXbins = self.member(\"fXbins\", none_if_missing=True)\n        fLabels = self.member(\"fLabels\", none_if_missing=True)\n\n        if fLabels is not None and len(fLabels) == fNbins:\n            return str(fLabels[where])\n\n        elif fXbins is None or len(fXbins) != fNbins + 1:\n            fXmin, fXmax = self.member(\"fXmin\"), self.member(\"fXmax\")\n            low = (fXmax - fXmin) * (where) / float(fNbins) + fXmin\n            high = (fXmax - fXmin) * (where + 1) / float(fNbins) + fXmin\n            return low, high\n\n        else:\n            return fXbins[where + 1], fXbins[where + 2]\n\n    def __iter__(self):\n        \"\"\"\n        Iterate over the output of ``__getitem__``.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fLabels = self.member(\"fLabels\", none_if_missing=True)\n\n        if fLabels is not None and len(fLabels) == fNbins:\n            for x in fLabels:\n                yield str(x)\n        else:\n            for low, high in self.intervals():\n                yield low, high\n\n    def __eq__(self, other):\n        \"\"\"\n        Two axes are equal if they have the same type and\n        ``list(self) == list(other)``.\n        \"\"\"\n        if type(self) is not type(other):\n            return False\n\n        self_fNbins = self.member(\"fNbins\")\n        other_fNbins = other.member(\"fNbins\")\n        if self_fNbins != other_fNbins:\n            return False\n\n        self_fLabels = self.member(\"fLabels\", none_if_missing=True)\n        other_fLabels = other.member(\"fLabels\", none_if_missing=True)\n        self_labeled = self_fLabels is not None and len(self_fLabels) == self_fNbins\n        other_labeled = other_fLabels is not None and len(other_fLabels) == other_fNbins\n\n        if self_labeled and other_labeled:\n            return all(x == y for x, y in zip(self_fLabels, other_fLabels))\n        elif not self_labeled and not other_labeled:\n            return numpy.array_equal(self.edges(), other.edges())\n        else:\n            return False\n\n    def __ne__(self, other):\n        \"\"\"\n        Some versions of Python don't automatically negate __eq__.\n        \"\"\"\n        return not self.__eq__(other)\n\n    @property\n    def traits(self):\n        \"\"\"\n        Describes read-only properties of a histogram axis.\n\n        For example, ``axis.traits.discrete`` is True if the histogram has\n        labels; False otherwise.\n        \"\"\"\n        return AxisTraits(self)\n\n    @property\n    def low(self):\n        \"\"\"\n        The low edge of the first normal (finite-width) bin.\n\n        For ROOT histograms, numerical edges exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        return self.member(\"fXmin\")\n\n    @property\n    def high(self):\n        \"\"\"\n        The high edge of the last normal (finite-width) bin.\n\n        For ROOT histograms, numerical edges exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        return self.member(\"fXmax\")\n\n    @property\n    def width(self):\n        \"\"\"\n        The average bin width (or only bin width if the binning is uniform).\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fXbins = self.member(\"fXbins\", none_if_missing=True)\n\n        if fXbins is None or len(fXbins) != fNbins + 1:\n            return (self.member(\"fXmax\") - self.member(\"fXmin\")) / fNbins\n        else:\n            return self.widths().mean()\n\n    def labels(self, flow=False):\n        \"\"\"\n        Args:\n            flow (bool): If True, include ``\"underflow\"`` and ``\"overflow\"``\n                before and after the normal (finite-width) bin labels (if they\n                exist).\n\n        If string-valued labels exist, this returns them as a Python list of\n        Python strings. Otherwise, this returns None.\n\n        Setting ``flow=True`` increases the length of the output by two.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fLabels = self.member(\"fLabels\", none_if_missing=True)\n\n        if fLabels is not None and len(fLabels) == fNbins:\n            out = [str(x) for x in fLabels]\n            if flow:\n                return [\"underflow\"] + out + [\"overflow\"]\n            else:\n                return out\n        else:\n            return None\n\n    def edges(self, flow=False):\n        \"\"\"\n        Args:\n            flow (bool): If True, include ``-inf`` and ``inf`` before and\n                after the normal (finite-width) bin edges.\n\n        Returns numerical edges between bins as a one-dimensional ``numpy.ndarray``\n        of ``numpy.float64``.\n\n        Even with ``flow=False``, the number of edges is *one greater than* the\n        number of normal (finite-width) bins because they represent \"fenceposts\"\n        between the bins, including one below and one above the full range.\n\n        Setting ``flow=True`` increases the length of the output by two.\n\n        For ROOT histograms, numerical edges exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fXbins = self.member(\"fXbins\", none_if_missing=True)\n\n        if fXbins is None or len(fXbins) != fNbins + 1:\n            fXbins = numpy.linspace(\n                self.member(\"fXmin\"), self.member(\"fXmax\"), fNbins + 1\n            )\n\n        if flow:\n            out = numpy.empty(fNbins + 3, dtype=numpy.float64)\n            out[0] = -numpy.inf\n            out[-1] = numpy.inf\n            out[1:-1] = fXbins\n        else:\n            out = numpy.asarray(fXbins, dtype=fXbins.dtype.newbyteorder(\"=\"))\n\n        return out\n\n    def intervals(self, flow=False):\n        \"\"\"\n        Args:\n            flow (bool): If True, include ``[-inf, min]`` and ``[max, inf]``\n                before and after the normal (finite-width) intervals.\n\n        Returns low, high pairs for each bin interval as a two-dimensional\n        ``numpy.ndarray`` of ``numpy.float64``.\n\n        With ``flow=False``, the number of intervals is equal to the number of\n        normal (finite-width) bins.\n\n        Setting ``flow=True`` increases the length of the output by two.\n\n        For ROOT histograms, numerical intervals exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fXbins = self.member(\"fXbins\", none_if_missing=True)\n\n        if fXbins is None or len(fXbins) != fNbins + 1:\n            fXbins = numpy.linspace(\n                self.member(\"fXmin\"), self.member(\"fXmax\"), fNbins + 1\n            )\n\n        if flow:\n            out = numpy.empty((fNbins + 2, 2), dtype=numpy.float64)\n            out[0, 0] = -numpy.inf\n            out[-1, 1] = numpy.inf\n            out[1:, 0] = fXbins\n            out[:-1, 1] = fXbins\n        else:\n            out = numpy.empty((fNbins, 2), dtype=numpy.float64)\n            out[:, 0] = fXbins[:-1]\n            out[:, 1] = fXbins[1:]\n\n        return out\n\n    def centers(self, flow=False):\n        \"\"\"\n        Args:\n            flow (bool): If True, include ``-inf`` and ``inf`` before and after\n                the normal (finite) bin centers.\n\n        Returns bin center positions as a one-dimensional ``numpy.ndarray`` of\n        ``numpy.float64``.\n\n        With ``flow=False``, the number of bin centers is equal to the number of\n        normal (finite-width) bins.\n\n        Setting ``flow=True`` increases the length of the output by two.\n\n        For ROOT histograms, numerical bin centers exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        edges = self.edges(flow=flow)\n        return (edges[1:] + edges[:-1]) / 2.0\n\n    def widths(self, flow=False):\n        \"\"\"\n        Args:\n            flow (bool): If True, include ``-inf`` and ``inf`` before and after\n                the normal (finite) bin widths.\n\n        Returns bin widths as a one-dimensional ``numpy.ndarray`` of\n        ``numpy.float64``.\n\n        With ``flow=False``, the number of bin widths is equal to the number of\n        normal (finite-width) bins.\n\n        Setting ``flow=True`` increases the length of the output by two.\n\n        For ROOT histograms, numerical bin widths exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fXbins = self.member(\"fXbins\", none_if_missing=True)\n\n        if not flow and (fXbins is None or len(fXbins) != fNbins + 1):\n            width = (self.member(\"fXmax\") - self.member(\"fXmin\")) / fNbins\n            return numpy.broadcast_to(width, (fNbins,))\n        else:\n            edges = self.edges(flow=flow)\n            return edges[1:] - edges[:-1]\n", "path": "uproot/behaviors/TAxis.py"}], "after_files": [{"content": "# BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/main/LICENSE\n\n\"\"\"\nThis module defines the behaviors of ``TAxis``, an axis of a histogram or profile plot.\n\"\"\"\n\nfrom __future__ import absolute_import\n\ntry:\n    from collections.abc import Sequence\nexcept ImportError:\n    from collections import Sequence\n\nimport numpy\n\n\nclass AxisTraits(object):\n    \"\"\"\n    Describes read-only properties of a histogram axis.\n\n    For example, ``axis.traits.discrete`` is True if the histogram has\n    labels; False otherwise.\n    \"\"\"\n\n    def __init__(self, axis):\n        self._axis = axis\n\n    def __repr__(self):\n        return \"AxisTraits({0})\".format(repr(self._axis))\n\n    @property\n    def circular(self):\n        \"\"\"\n        True if the axis \"wraps around\" (always False for ROOT histograms).\n        \"\"\"\n        return False\n\n    @property\n    def discrete(self):\n        \"\"\"\n        True if bins are discrete: if they have string-valued labels.\n        \"\"\"\n        fNbins = self._axis.member(\"fNbins\")\n        fLabels = self._axis.member(\"fLabels\", none_if_missing=True)\n        return fLabels is not None and len(fLabels) == fNbins\n\n\nclass TAxis(Sequence):\n    def __len__(self):\n        \"\"\"\n        The number of bins in the axis.\n        \"\"\"\n        return self.member(\"fNbins\")\n\n    def __getitem__(self, where):\n        \"\"\"\n        Returns the label at ``where`` if it exists or the interval at ``where``.\n\n        The indexing assumes that ``flow=False``.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fXbins = self.member(\"fXbins\", none_if_missing=True)\n        fLabels = self.member(\"fLabels\", none_if_missing=True)\n\n        if fLabels is not None and len(fLabels) == fNbins:\n            return str(fLabels[where])\n\n        elif fXbins is None or len(fXbins) != fNbins + 1:\n            fXmin, fXmax = self.member(\"fXmin\"), self.member(\"fXmax\")\n            low = (fXmax - fXmin) * (where) / float(fNbins) + fXmin\n            high = (fXmax - fXmin) * (where + 1) / float(fNbins) + fXmin\n            return low, high\n\n        else:\n            return fXbins[where], fXbins[where + 1]\n\n    def __iter__(self):\n        \"\"\"\n        Iterate over the output of ``__getitem__``.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fLabels = self.member(\"fLabels\", none_if_missing=True)\n\n        if fLabels is not None and len(fLabels) == fNbins:\n            for x in fLabels:\n                yield str(x)\n        else:\n            for low, high in self.intervals():\n                yield low, high\n\n    def __eq__(self, other):\n        \"\"\"\n        Two axes are equal if they have the same type and\n        ``list(self) == list(other)``.\n        \"\"\"\n        if type(self) is not type(other):\n            return False\n\n        self_fNbins = self.member(\"fNbins\")\n        other_fNbins = other.member(\"fNbins\")\n        if self_fNbins != other_fNbins:\n            return False\n\n        self_fLabels = self.member(\"fLabels\", none_if_missing=True)\n        other_fLabels = other.member(\"fLabels\", none_if_missing=True)\n        self_labeled = self_fLabels is not None and len(self_fLabels) == self_fNbins\n        other_labeled = other_fLabels is not None and len(other_fLabels) == other_fNbins\n\n        if self_labeled and other_labeled:\n            return all(x == y for x, y in zip(self_fLabels, other_fLabels))\n        elif not self_labeled and not other_labeled:\n            return numpy.array_equal(self.edges(), other.edges())\n        else:\n            return False\n\n    def __ne__(self, other):\n        \"\"\"\n        Some versions of Python don't automatically negate __eq__.\n        \"\"\"\n        return not self.__eq__(other)\n\n    @property\n    def traits(self):\n        \"\"\"\n        Describes read-only properties of a histogram axis.\n\n        For example, ``axis.traits.discrete`` is True if the histogram has\n        labels; False otherwise.\n        \"\"\"\n        return AxisTraits(self)\n\n    @property\n    def low(self):\n        \"\"\"\n        The low edge of the first normal (finite-width) bin.\n\n        For ROOT histograms, numerical edges exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        return self.member(\"fXmin\")\n\n    @property\n    def high(self):\n        \"\"\"\n        The high edge of the last normal (finite-width) bin.\n\n        For ROOT histograms, numerical edges exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        return self.member(\"fXmax\")\n\n    @property\n    def width(self):\n        \"\"\"\n        The average bin width (or only bin width if the binning is uniform).\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fXbins = self.member(\"fXbins\", none_if_missing=True)\n\n        if fXbins is None or len(fXbins) != fNbins + 1:\n            return (self.member(\"fXmax\") - self.member(\"fXmin\")) / fNbins\n        else:\n            return self.widths().mean()\n\n    def labels(self, flow=False):\n        \"\"\"\n        Args:\n            flow (bool): If True, include ``\"underflow\"`` and ``\"overflow\"``\n                before and after the normal (finite-width) bin labels (if they\n                exist).\n\n        If string-valued labels exist, this returns them as a Python list of\n        Python strings. Otherwise, this returns None.\n\n        Setting ``flow=True`` increases the length of the output by two.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fLabels = self.member(\"fLabels\", none_if_missing=True)\n\n        if fLabels is not None and len(fLabels) == fNbins:\n            out = [str(x) for x in fLabels]\n            if flow:\n                return [\"underflow\"] + out + [\"overflow\"]\n            else:\n                return out\n        else:\n            return None\n\n    def edges(self, flow=False):\n        \"\"\"\n        Args:\n            flow (bool): If True, include ``-inf`` and ``inf`` before and\n                after the normal (finite-width) bin edges.\n\n        Returns numerical edges between bins as a one-dimensional ``numpy.ndarray``\n        of ``numpy.float64``.\n\n        Even with ``flow=False``, the number of edges is *one greater than* the\n        number of normal (finite-width) bins because they represent \"fenceposts\"\n        between the bins, including one below and one above the full range.\n\n        Setting ``flow=True`` increases the length of the output by two.\n\n        For ROOT histograms, numerical edges exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fXbins = self.member(\"fXbins\", none_if_missing=True)\n\n        if fXbins is None or len(fXbins) != fNbins + 1:\n            fXbins = numpy.linspace(\n                self.member(\"fXmin\"), self.member(\"fXmax\"), fNbins + 1\n            )\n\n        if flow:\n            out = numpy.empty(fNbins + 3, dtype=numpy.float64)\n            out[0] = -numpy.inf\n            out[-1] = numpy.inf\n            out[1:-1] = fXbins\n        else:\n            out = numpy.asarray(fXbins, dtype=fXbins.dtype.newbyteorder(\"=\"))\n\n        return out\n\n    def intervals(self, flow=False):\n        \"\"\"\n        Args:\n            flow (bool): If True, include ``[-inf, min]`` and ``[max, inf]``\n                before and after the normal (finite-width) intervals.\n\n        Returns low, high pairs for each bin interval as a two-dimensional\n        ``numpy.ndarray`` of ``numpy.float64``.\n\n        With ``flow=False``, the number of intervals is equal to the number of\n        normal (finite-width) bins.\n\n        Setting ``flow=True`` increases the length of the output by two.\n\n        For ROOT histograms, numerical intervals exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fXbins = self.member(\"fXbins\", none_if_missing=True)\n\n        if fXbins is None or len(fXbins) != fNbins + 1:\n            fXbins = numpy.linspace(\n                self.member(\"fXmin\"), self.member(\"fXmax\"), fNbins + 1\n            )\n\n        if flow:\n            out = numpy.empty((fNbins + 2, 2), dtype=numpy.float64)\n            out[0, 0] = -numpy.inf\n            out[-1, 1] = numpy.inf\n            out[1:, 0] = fXbins\n            out[:-1, 1] = fXbins\n        else:\n            out = numpy.empty((fNbins, 2), dtype=numpy.float64)\n            out[:, 0] = fXbins[:-1]\n            out[:, 1] = fXbins[1:]\n\n        return out\n\n    def centers(self, flow=False):\n        \"\"\"\n        Args:\n            flow (bool): If True, include ``-inf`` and ``inf`` before and after\n                the normal (finite) bin centers.\n\n        Returns bin center positions as a one-dimensional ``numpy.ndarray`` of\n        ``numpy.float64``.\n\n        With ``flow=False``, the number of bin centers is equal to the number of\n        normal (finite-width) bins.\n\n        Setting ``flow=True`` increases the length of the output by two.\n\n        For ROOT histograms, numerical bin centers exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        edges = self.edges(flow=flow)\n        return (edges[1:] + edges[:-1]) / 2.0\n\n    def widths(self, flow=False):\n        \"\"\"\n        Args:\n            flow (bool): If True, include ``-inf`` and ``inf`` before and after\n                the normal (finite) bin widths.\n\n        Returns bin widths as a one-dimensional ``numpy.ndarray`` of\n        ``numpy.float64``.\n\n        With ``flow=False``, the number of bin widths is equal to the number of\n        normal (finite-width) bins.\n\n        Setting ``flow=True`` increases the length of the output by two.\n\n        For ROOT histograms, numerical bin widths exist even if the axis also has\n        string-valued labels.\n        \"\"\"\n        fNbins = self.member(\"fNbins\")\n        fXbins = self.member(\"fXbins\", none_if_missing=True)\n\n        if not flow and (fXbins is None or len(fXbins) != fNbins + 1):\n            width = (self.member(\"fXmax\") - self.member(\"fXmin\")) / fNbins\n            return numpy.broadcast_to(width, (fNbins,))\n        else:\n            edges = self.edges(flow=flow)\n            return edges[1:] - edges[:-1]\n", "path": "uproot/behaviors/TAxis.py"}]}