docs: def check_climatological_statistics(self, ds):
          """
          7.4 A climatological time coordinate variable does not have a bounds attribute. Instead, it has a climatology
          attribute, which names a variable with dimensions (n,2), n being the dimension of the climatological time axis.
          Using the units and calendar of the time coordinate variable, element (i,0) of the climatology variable specifies
          the beginning of the first subinterval and element (i,1) the end of the last subinterval used to evaluate the
          climatological statistics with index i in the time dimension. The time coordinates should be values that are
          representative of the climatological time intervals, such that an application which does not recognise climatological
          time will nonetheless be able to make a reasonable interpretation.
  
          A climatological axis may use different statistical methods to measure variation among years, within years, and within
          days. The methods which can be specified are those listed in Appendix E, Cell Methods and each entry in the cell_methods
          attribute may also contain non-standardised information in parentheses after the method. The value of the cell_method
          attribute must be in one of the following forms:
          - time: method1 within years   time: method2 over years
          - time: method1 within days    time: method2 over days
          - time: method1 within days    time: method2 over days   time: method3 over years
  
          :param netCDF4.Dataset ds: An open netCDF dataset
          :rtype: list
          :return: List of results
          """
  
          reasoning = []
          ret_val = []
          total_climate_count = 0
          valid_climate_count = 0
          all_clim_coord_var_names = []
  
          methods = [ 'point', # TODO change to appendix import once cf1.7 merged
                      'sum',
                      'mean',
                      'maximum',
                      'minimum',
                      'mid_range',
                      'standard_deviation',
                      'variance',
                      'mode',
                      'median']
  
          # find any climatology axies variables; any variables which contain climatological stats will use
          # these variables as coordinates
          clim_time_coord_vars = ds.get_variables_by_attributes(
              climatology=lambda s: s is not None)
  
          # first, to determine whether or not we have a valid climatological time
          # coordindate variable, we need to make sure it has the attribute "climatology",
          # but not the attribute "bounds"
          for clim_coord_var in clim_time_coord_vars:
              if hasattr(clim_coord_var, 'bounds'):
                  reasoning.append('Variable {} has a climatology attribute and cannot also have a bounds attribute.'.format(clim_coord_var.name))
                  result = Result(BaseCheck.MEDIUM,
                                  False,
                                  (self.section_titles['7.4']),
                                  reasoning)
                  ret_val.append(result)
                  return ret_val
  
              # make sure the climatology variable referenced actually exists
              elif clim_coord_var.climatology not in ds.variables:
                  reasoning.append("Variable {} referenced in time's climatology attribute does not exist".format(ds.variables['time'].climatology))
                  result = Result(BaseCheck.MEDIUM,
                                  False,
                                  (self.section_titles['7.4']),
                                  reasoning)
                  ret_val.append(result)
                  return ret_val
  
  
              # check that coordinate bounds are in the proper order.
              # make sure last elements are boundary variable specific dimensions
              if (clim_coord_var.dimensions[:] !=
                    ds.variables[clim_coord_var.climatology].dimensions[:clim_coord_var.ndim]):
                  reasoning.append(
                      u"Climatology variable coordinates are in improper order: {}. Bounds-specific dimensions should be last".format(
                          ds.variables[clim_coord_var.climatology].dimensions)
                  )
                  return ret_val
  
              elif ds.dimensions[ds.variables[clim_coord_var.climatology].dimensions[-1]].size != 2:
                  reasoning.append(
                      u"Climatology dimension {} should only contain two elements".format(
                          boundary_variable.dimensions)
                  )
  
              # passed all these checks, so we can add this clim_coord_var to our total list
              all_clim_coord_var_names.append(clim_coord_var.name)
  
          # for any variables which use a climatology time coordinate variable as a coordinate,
          # if they have a cell_methods attribute, it must comply with the form:
          #     time: method1 within years time: method2 over years
          #     time: method1 within days time: method2 over days
          #     time: method1 within days time: method2 over days time: method3 over years
          # optionally followed by parentheses for explaining additional
          # info, e.g.
          # "time: method1 within years time: method2 over years (sidereal years)"
  
          meth_regex = "(?:{})".format("|".join(methods)) # "or" comparison for the methods
          re_string = (r'^time: {0} within (years|days)'  # regex string to test
                       r' time: {0} over \1(?<=days)(?: time: {0} over years)?'
                       r'(?: \([^)]+\))?$'.format(meth_regex))
  
          # find any variables with a valid climatological cell_methods
          for cell_method_var in ds.get_variables_by_attributes(cell_methods=lambda s: s is not None):
              if any([dim in all_clim_coord_var_names for dim in cell_method_var.dimensions]):
                  total_climate_count += 1
                  if not regex.search(re_string, cell_method_var.cell_methods):
                      reasoning.append('The "time: method within years/days over years/days" format is not correct in variable {}.'.format(cell_method_var.name))
                  else:
                      valid_climate_count += 1
  
                  result = Result(BaseCheck.MEDIUM,
                                  (valid_climate_count, total_climate_count),
                                  (self.section_titles['7.4']),
                                  reasoning)
                  ret_val.append(result)
  
          return ret_val