code: def test_synthetic_shadow_model(art_warning):
      try:
          (x_train, y_train), (_, _), _, _ = load_nursery(test_set=0.2)
  
          model = RandomForestClassifier(random_state=7)
          model.fit(x_train, y_train)
          art_classifier = ScikitlearnRandomForestClassifier(model)
  
          shadow_models = ShadowModels(
              art_classifier, num_shadow_models=1, random_state=7
          )
          record_rng = np.random.default_rng(seed=7)
  
          def random_record() -> np.ndarray:
              children_values = [0.0, 0.33333333, 0.66666667, 1.0]
              categorical_features = [3, 5, 4, 3, 2, 3, 3]
              empty_record = np.zeros(1 + np.sum(categorical_features))
              empty_record[0] = record_rng.choice(children_values)
  
              offset = 1
              for feature_options in categorical_features:
                  chosen_option = record_rng.integers(feature_options)
                  empty_record[offset + chosen_option] = 1.0
                  offset += feature_options
  
              return empty_record
  
          def randomize_features(
              record: np.ndarray, num_features: int
          ) -> np.ndarray:
              children_values = [0.0, 0.33333333, 0.66666667, 1.0]
              categorical_features = [3, 5, 4, 3, 2, 3, 3]
  
              new_record = record.copy()
              for feature in record_rng.choice(8, size=num_features):
                  if feature == 0:
                      new_record[0] = record_rng.choice(children_values)
                  else:
                      cat_feature = feature - 1
  
                      one_hot = np.zeros(
                          categorical_features[cat_feature]
                      )
                      one_hot[
                          record_rng.integers(
                              categorical_features[cat_feature]
                          )
                      ] = 1.0
  
                      feature_offset = 1 + np.sum(
                          categorical_features[:cat_feature],
                          dtype=np.int64,
                      )
                      new_record[
                          feature_offset : feature_offset
                          + categorical_features[cat_feature]
                      ] = one_hot
  
              return new_record
  
          shadow_dataset = (
              shadow_models.generate_synthetic_shadow_dataset(
                  art_classifier,
                  40,
                  max_features_randomized=8,
                  random_record_fn=random_record,
                  randomize_features_fn=randomize_features,
              )
          )
          (mem_x, mem_y, mem_pred), (
              nonmem_x,
              nonmem_y,
              nonmem_pred,
          ) = shadow_dataset
  
          assert len(mem_x) == len(mem_y)
          assert len(mem_y) == len(mem_pred)
          assert len(nonmem_x) == len(nonmem_y)
          assert len(nonmem_y) == len(nonmem_pred)
          assert len(mem_x) + len(mem_y) == 40
  
      except ARTTestException as e:
          art_warning(e)
  
file_path: adversarial-robustness-toolbox/tests/attacks/inference/membership_inference/test_shadow_models.py
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  import numpy
  import pytest
  from sklearn.ensemble import RandomForestClassifier
  from art.attacks.inference.membership_inference.black_box import MembershipInferenceBlackBox
  from art.attacks.inference.membership_inference.shadow_models import ShadowModels
  from art.estimators.classification.scikitlearn import ScikitlearnRandomForestClassifier, ScikitlearnClassifier
  from art.utils import load_nursery, to_categorical
  from tests.utils import ARTTestException
label_desc: Use image node_id 4 for calling a global function with example usage: test_synthetic_shadow_model(art_warning) and returns: empty_record, new_record