code: def _pp_ops(
      train: bool,
      # Visual args:
      visual_key: str = "image",
      is_video: bool = False,
      num_frames: int = 16,
      stride: int = 14,
      min_resize: int = 256,
      crop_size: Union[int, Sequence[int, int]] = 224,
      resizing_method: str = "bicubic",
      normalization_mean: Union[Sequence[int], int] = 0,
      normalization_std: Union[Sequence[int], int] = 1,
      # Text args:
      text_in_key: str = "texts",
      text_out_key: str = "labels",
      is_classification: bool = False,
      tokenizer_type: Literal["dmvr", "sentence_piece", ""] = "",
      tokenizer_name: str = "",  # Only used for the DMVR tokenizers.
      vocab_name_or_path: str = "",  # Only used for SentencePiece tokenizers.
      prepend_bos: bool = False,  # Only used for the DMVR tokenizers.
      append_eos: bool = True,
      lowercase: bool = False,  # Only used for SentencePiece tokenizers.
      max_num_tokens: int = 77,
      pad_value: int = 0,  # Only used for SentencePiece tokenizers.
  ) -> str:
      """Returns the pre-processing operations string."""
      if is_video:
          # TODO(sacastro): support multiple clips.
          sample_step = (
              f"|sample_sequence(num_steps={1 if train else num_frames},"
              f"                 random={train}, stride={stride},"
              f'                 inkey="{visual_key}",'
              f'                 outkey="{visual_key}")'
          )
      else:
          sample_step = ""
  
      decode_fn_name = "decode_frames" if is_video else "decode"
  
      if not is_classification and tokenizer_type:
          text_sampling_fn = "random_sample" if train else "first"
          text_sampling_step = (
              f'|{text_sampling_fn}(inkey="{text_in_key}",'
              f'                    outkey="{text_out_key}")'
          )
      else:
          text_sampling_step = ""
  
      if tokenizer_type == "dmvr":
          # assert not lowercase  # This arg is used in other places.
          assert pad_value == 0
          vocab_name_or_path_str = (
              f'"{vocab_name_or_path}"' if vocab_name_or_path else None
          )
          tokenization_step = (
              f'|dmvr_tokenize("{tokenizer_name}",'
              f"               vocab_path={vocab_name_or_path_str},"
              f"               prepend_bos={prepend_bos},"
              f"               append_eos={append_eos},"
              f"               max_num_tokens={max_num_tokens},"
              f'               inkey="{text_out_key}",'
              f'               outkey="{text_out_key}")'
          )
      elif tokenizer_type == "sentence_piece":
          assert not prepend_bos
          tokenization_step = (
              f"|tokenize(max_len={max_num_tokens},"
              f'          eos="{"yes" if append_eos else "none"}",'
              f'          model="{vocab_name_or_path}",'
              f"          lower={lowercase},"
              f"          sample_if_multi={train},"
              f"          pad_value={pad_value},"
              f'          inkey="{text_out_key}",'
              f'          outkey="{text_out_key}")'
          )
      else:
          tokenization_step = ""
  
      return (
          f"{sample_step}"
          f'|{decode_fn_name}(inkey="{visual_key}", outkey="{visual_key}")'
          f'|resize_smallest({min_resize}, method="{resizing_method}",'
          f'                 inkey="{visual_key}", outkey="{visual_key}")'
          f'|{"random" if train else "central"}_crop({crop_size},'
          f'                                         inkey="{visual_key}",'
          f'                                         outkey="{visual_key}")'
          f'|value_range(0, 1, inkey="{visual_key}", outkey="{visual_key}")'
          f"|standardize(mean={normalization_mean}, std={normalization_std},"
          f'             inkey="{visual_key}", outkey="{visual_key}")'
          f"{text_sampling_step}"
          f"{tokenization_step}"
          f'|keep("{visual_key}", "{text_out_key}")'
      ).strip("|")
  
file_path: scenic/scenic/projects/lang4video/configs/base.py
imports: from collections.abc import Sequence
  from typing import Literal
  from typing import Union
  import ml_collections
label_desc: Use image node_id 1 for calling a global function with example usage: _pp_ops(train, visual_key, is_video, num_frames, stride, min_resize, crop_size, resizing_method, normalization_mean, normalization_std, text_in_key, text_out_key, is_classification, tokenizer_type, tokenizer_name, vocab_name_or_path, prepend_bos, append_eos, lowercase, max_num_tokens, pad_value) and returns: sample_step, str, decode_fn_name, str, visual_key, str, visual_key, str, min_resize, str, resizing_method, str, visual_key, str, visual_key, str, unknown, str, crop_size, str, visual_key, str, visual_key, str, visual_key, str, visual_key, str, normalization_mean, str, normalization_std, str, visual_key, str, visual_key, str, text_sampling_step, tokenization_step, str, visual_key, str, text_out_key, str