code: def prep_or_copy_df(
      df: pd.DataFrame,
  ) -> tuple[pd.DataFrame, bool, bool, list[str]]:
      """Copy df if it contains the ID column. Creates ID column with '__df__' if it is a df with a single time series.
      Parameters
      ----------
          df : pd.DataFrame
              df or dict containing data
      Returns
      -------
          pd.DataFrames
              df with ID col
          bool
              whether the ID col was present
          bool
              wheter it is a single time series
          list
              list of IDs
      """
      if not isinstance(df, pd.DataFrame):
          raise ValueError(
              "Provided DataFrame (df) must be of pd.DataFrame type."
          )
  
      # Create a copy of the dataframe
      df_copy = df.copy(deep=True)
  
      df_has_id_column = "ID" in df_copy.columns
  
      # If there is no ID column, then add one with a single value
      if not df_has_id_column:
          log.debug(
              "Provided DataFrame (df) contains a single time series."
          )
          df_copy["ID"] = "__df__"
          return df_copy, df_has_id_column, True, ["__df__"]
  
      # Create a list of unique ID values
      unique_id_values = list(df_copy["ID"].unique())
      # Check if there is only one unique ID value
      df_has_single_time_series = len(unique_id_values) == 1
  
      single_or_multiple_message = (
          "a single" if df_has_single_time_series else "multiple"
      )
      log.debug(
          f"Provided DataFrame (df) has an ID column and contains {single_or_multiple_message} time series."
      )
  
      return (
          df_copy,
          df_has_id_column,
          df_has_single_time_series,
          unique_id_values,
      )
  
imports: from __future__ import annotations
  import logging
  import math
  from collections import OrderedDict
  from dataclasses import dataclass
  from typing import TYPE_CHECKING, List, Optional, Tuple
  import numpy
  import pandas
label_desc: Use image node_id 1 for calling a global function with example usage: prep_or_copy_df(df) and returns: df_copy,  df_has_id_column,  df_has_single_time_series,  unique_id_values, df_copy,  df_has_id_column,  True,  list