code: def columns(self):
          
          if self.df.empty:
              return None
  
          columns = []
          sample_size = min(INFER_COL_TYPES_SAMPLE_SIZE, len(self.df.index))
          sample = self.df
          if sample_size:
              sample = self.df.sample(sample_size)
          for col in self.df.dtypes.keys():
              db_type_str = (
                  self._type_dict.get(col) or
                  self.db_type(self.df.dtypes[col])
              )
              column = {
                  'name': col,
                  'agg': self.agg_func(self.df.dtypes[col], col),
                  'type': db_type_str,
                  'is_date': self.is_date(self.df.dtypes[col], db_type_str),
                  'is_dim': self.is_dimension(self.df.dtypes[col], col),
              }
  
              if not db_type_str or db_type_str.upper() == 'OBJECT':
                  v = sample[col].iloc[0] if not sample[col].empty else None
                  if isinstance(v, str):
                      column['type'] = 'STRING'
                  elif isinstance(v, int):
                      column['type'] = 'INT'
                  elif isinstance(v, float):
                      column['type'] = 'FLOAT'
                  elif isinstance(v, (datetime, date)):
                      column['type'] = 'DATETIME'
                      column['is_date'] = True
                      column['is_dim'] = False
                  # check if encoded datetime
                  if (
                          column['type'] == 'STRING' and
                          self.datetime_conversion_rate(sample[col]) >
                          INFER_COL_TYPES_THRESHOLD):
                      column.update({
                          'is_date': True,
                          'is_dim': False,
                          'agg': None,
                      })
              # 'agg' is optional attribute
              if not column['agg']:
                  column.pop('agg', None)
              columns.append(column)
          return columns
docs: Provides metadata about columns for data visualization.
  
          :return: dict, with the fields name, type, is_date, is_dim and agg.