code: def generate_nvt_features(self):
      logging.info(
          "Generating NVTabular workflow for preprocessing features"
      )
      args = self.args
      feats = dict()
  
      feats[INDEX_TMP_COL] = [INDEX_TMP_COL]
  
      for col in args.control_features:
          feats[col] = [col]
  
      for col in args.categorical_features:
          feats[col] = [col] >> nvt_ops.Categorify(
              freq_threshold=args.categ_min_freq_capping,
              out_path=NVT_OUTPUT_FOLDER,
          )
      for col in args.continuous_features:
          feats[col] = [col]
          if args.continuous_features_fillna is not None:
              if args.continuous_features_fillna.lower() == "median":
                  feats[col] = feats[col] >> nvt_ops.FillMedian()
              else:
                  feats[col] = feats[col] >> nvt_ops.FillMissing(
                      args.continuous_features_fillna
                  )
          feats[col] = feats[col] >> nvt_ops.Normalize()
  
      if args.target_encoding_features or args.target_encoding_targets:
          if not args.target_encoding_features:
              args.target_encoding_features = args.categorical_features
          if not args.target_encoding_targets:
              args.target_encoding_targets = (
                  args.binary_classif_targets + args.regression_targets
              )
  
          if (
              args.target_encoding_targets
              and args.target_encoding_features
          ):
              for target_col in args.target_encoding_targets:
                  feats[f"{target_col}_te_features"] = (
                      args.target_encoding_features
                      >> nvt.ops.TargetEncoding(
                          [target_col],
                          kfold=args.target_encoding_kfold,
                          p_smooth=args.target_encoding_smoothing,
                          out_dtype="float32",
                      )
                  )
  
      for col in args.user_features:
          feats[col] = feats[col] >> nvt_ops.TagAsUserFeatures()
      for col in args.item_features:
          feats[col] = feats[col] >> nvt_ops.TagAsItemFeatures()
  
      if args.user_id_feature:
          feats[args.user_id_feature] = (
              feats[args.user_id_feature] >> nvt_ops.TagAsUserID()
          )
  
      if args.item_id_feature:
          feats[args.item_id_feature] = (
              feats[args.item_id_feature] >> nvt_ops.TagAsItemID()
          )
  
      if args.timestamp_feature:
          feats[args.timestamp_feature] = [
              args.timestamp_feature
          ] >> nvt_ops.AddTags([Tags.TIME])
  
      if args.session_id_feature:
          feats[args.session_id_feature] = [
              args.session_id_feature
          ] >> nvt_ops.AddTags([Tags.SESSION_ID, Tags.SESSION, Tags.ID])
  
      # Combining all features
      outputs = reduce(lambda x, y: x + y, list(feats.values()))
  
      return outputs
  
imports: import gc
  import logging
  import os
  import shutil
  from functools import reduce
  from typing import Optional
  import nvtabular
  from merlin.core.dispatch import HAS_GPU
  from merlin.schema import Tags
  from nvtabular import ops
  from .args_parsing import parse_arguments
label_desc: Use image node_id 8 for calling the PreprocessingRunner obj's underlying member method code with example usage: obj.generate_nvt_features() and returns: outputs