code: def _get_bin_edges(a, bins, range, weights):
      """
      Computes the bins used internally by `histogram`.
  
      Parameters
      ==========
      a : ndarray
          Ravelled data array
      bins, range
          Forwarded arguments from `histogram`.
      weights : ndarray, optional
          Ravelled weights array, or None
  
      Returns
      =======
      bin_edges : ndarray
          Array of bin edges
      uniform_bins : (Number, Number, int):
          The upper bound, lowerbound, and number of bins, used in the optimized
          implementation of `histogram` that works on uniform bins.
      """
      # parse the overloaded bins argument
      n_equal_bins = None
      bin_edges = None
  
      if isinstance(bins, str):
          bin_name = bins
          # if `bins` is a string for an automatic method,
          # this will replace it with the number of bins calculated
          if bin_name not in _hist_bin_selectors:
              raise ValueError(
                  "{!r} is not a valid estimator for `bins`".format(
                      bin_name
                  )
              )
          if weights is not None:
              raise TypeError(
                  "Automated estimation of the number of "
                  "bins is not supported for weighted data"
              )
  
          first_edge, last_edge = _get_outer_edges(a, range)
  
          # truncate the range if needed
          if range is not None:
              keep = a >= first_edge
              keep &= a <= last_edge
              if not np.logical_and.reduce(keep):
                  a = a[keep]
  
          if a.size == 0:
              n_equal_bins = 1
          else:
              # Do not call selectors on empty arrays
              width = _hist_bin_selectors[bin_name](
                  a, (first_edge, last_edge)
              )
              if width:
                  n_equal_bins = int(
                      np.ceil(
                          _unsigned_subtract(last_edge, first_edge)
                          / width
                      )
                  )
              else:
                  # Width can be zero for some estimators, e.g. FD when
                  # the IQR of the data is zero.
                  n_equal_bins = 1
  
      elif np.ndim(bins) == 0:
          try:
              n_equal_bins = operator.index(bins)
          except TypeError as e:
              raise TypeError(
                  "`bins` must be an integer, a string, or an array"
              ) from e
          if n_equal_bins < 1:
              raise ValueError(
                  "`bins` must be positive, when an integer"
              )
  
          first_edge, last_edge = _get_outer_edges(a, range)
  
      elif np.ndim(bins) == 1:
          bin_edges = np.asarray(bins)
          if np.any(bin_edges[:-1] > bin_edges[1:]):
              raise ValueError(
                  "`bins` must increase monotonically, when an array"
              )
  
      else:
          raise ValueError("`bins` must be 1d, when an array")
  
      if n_equal_bins is not None:
          # gh-10322 means that type resolution rules are dependent on array
          # shapes. To avoid this causing problems, we pick a type now and stick
          # with it throughout.
          bin_type = np.result_type(first_edge, last_edge, a)
          if np.issubdtype(bin_type, np.integer):
              bin_type = np.result_type(bin_type, float)
  
          # bin edges must be computed
          bin_edges = np.linspace(
              first_edge,
              last_edge,
              n_equal_bins + 1,
              endpoint=True,
              dtype=bin_type,
          )
          return bin_edges, (first_edge, last_edge, n_equal_bins)
      else:
          return bin_edges, None
  
imports: import contextlib
  import functools
  import operator
  import warnings
  import numpy
  from numpy._core import overrides
label_desc: Use image node_id 13 for calling a global function with example usage: _get_bin_edges(a, bins, range, weights) and returns: bin_edges,  first_edge,  last_edge,  n_equal_bins, bin_edges,  None