code: def normalize_crypto(
      df: pd.DataFrame,
      calendar_list: list = None,
      date_field_name: str = "date",
      symbol_field_name: str = "symbol",
  ):
      if df.empty:
          return df
      df = df.copy()
      df.set_index(date_field_name, inplace=True)
      df.index = pd.to_datetime(df.index)
      df = df[~df.index.duplicated(keep="first")]
      if calendar_list is not None:
          df = df.reindex(
              pd.DataFrame(index=calendar_list)
              .loc[
                  pd.Timestamp(df.index.min())
                  .date() : pd.Timestamp(df.index.max())
                  .date()
                  + pd.Timedelta(hours=23, minutes=59)
              ]
              .index
          )
      df.sort_index(inplace=True)
  
      df.index.names = [date_field_name]
      return df.reset_index()
  
imports: import abc
  import sys
  import datetime
  from abc import ABC
  from pathlib import Path
  import fire
  import pandas
  from loguru import logger
  from dateutil.tz import tzlocal
  from data_collector.base import BaseCollector, BaseNormalize, BaseRun
  from data_collector.utils import deco_retry
  from pycoingecko import CoinGeckoAPI
  from time import mktime
  from datetime import datetime
  import time
label_desc: Use image node_id 1 for calling the CryptoNormalize obj's underlying member method code with example usage: obj.normalize_crypto(df, calendar_list, date_field_name, symbol_field_name) and returns: df, df