code: def construct_bins(
      X,
      y,
      sample_weight,
      feature_names_given,
      feature_types_given,
      max_bins_leveled,
      binning="quantile",
      min_samples_bin=1,
      min_unique_continuous=0,
      seed=None,
      epsilon=None,
      delta=None,
      composition=None,
      privacy_bounds=None,
  ):
      is_mains = True
      for max_bins in max_bins_leveled:
          preprocessor = EBMPreprocessor(
              feature_names_given,
              feature_types_given,
              max_bins,
              binning,
              min_samples_bin,
              min_unique_continuous,
              seed,
              epsilon,
              delta,
              composition,
              privacy_bounds,
          )
  
          seed = increment_seed(seed)
  
          preprocessor.fit(X, y, sample_weight)
          if is_mains:
              is_mains = False
              bins = preprocessor.bins_
              for feature_idx in range(len(bins)):
                  bins[feature_idx] = [bins[feature_idx]]
  
              feature_names_in = preprocessor.feature_names_in_
              feature_types_in = preprocessor.feature_types_in_
              bin_weights = preprocessor.bin_weights_
              feature_bounds = preprocessor.feature_bounds_
              histogram_weights = preprocessor.histogram_weights_
              missing_val_counts = preprocessor.missing_val_counts_
              unique_val_counts = preprocessor.unique_val_counts_
              noise_scale = preprocessor.noise_scale_
          else:
              if feature_names_in != preprocessor.feature_names_in_:
                  raise RuntimeError("Mismatched feature_names")
              if feature_types_in != preprocessor.feature_types_in_:
                  raise RuntimeError("Mismatched feature_types")
              if len(bins) != len(preprocessor.bins_):
                  raise RuntimeError("Mismatched bin lengths")
  
              for bin_levels, feature_bins in zip(
                  bins, preprocessor.bins_
              ):
                  bin_levels.append(feature_bins)
  
      return (
          feature_names_in,
          feature_types_in,
          bins,
          bin_weights,
          feature_bounds,
          histogram_weights,
          missing_val_counts,
          unique_val_counts,
          noise_scale,
      )
  
imports: import logging
  import math
  from itertools import count, repeat, groupby
  from warnings import warn
  import numpy
  from sklearn.base import BaseEstimator, TransformerMixin
  from sklearn.utils.validation import check_is_fitted
  from ._clean_x import unify_columns, preclean_X, unify_feature_names
  from ._clean_simple import clean_dimensions
  from ._seed import normalize_seed, increment_seed
  from ._native import Native
  from ._privacy import validate_eps_delta, calc_classic_noise_multi, calc_gdp_noise_multi, private_numeric_binning, private_categorical_binning
label_desc: Use image node_id 2 for calling a global function with example usage: construct_bins(X, y, sample_weight, feature_names_given, feature_types_given, max_bins_leveled, binning, min_samples_bin, min_unique_continuous, seed, epsilon, delta, composition, privacy_bounds) and returns: feature_names_in,  feature_types_in,  bins,  bin_weights,  feature_bounds,  histogram_weights,  missing_val_counts,  unique_val_counts,  noise_scale