code: def _precheck(self, curtailment_timeseries, feedin_df, curtailment_key):
          
          if not feedin_df.empty:
              feedin_selected_sum = feedin_df.sum(axis=1)
              diff = feedin_selected_sum - curtailment_timeseries
              # add tolerance (set small negative values to zero)
              diff[diff.between(-1, 0)] = 0
              if not (diff >= 0).all():
                  bad_time_steps = [_ for _ in diff.index
                                    if diff[_] < 0]
                  message = 'Curtailment demand exceeds total feed-in in time ' \
                            'steps {}.'.format(bad_time_steps)
                  logging.error(message)
                  raise ValueError(message)
          else:
              bad_time_steps = [_ for _ in curtailment_timeseries.index
                                if curtailment_timeseries[_] > 0]
              if bad_time_steps:
                  message = 'Curtailment given for time steps {} but there ' \
                            'are no generators to meet the curtailment target ' \
                            'for {}.'.format(bad_time_steps, curtailment_key)
                  logging.error(message)
                  raise ValueError(message)
docs: Raises an error if the curtailment at any time step exceeds the
          total feed-in of all generators curtailment can be distributed among
          at that time.
  
          Parameters
          -----------
          curtailment_timeseries : :pandas:`pandas.Series<series>`
              Curtailment time series in kW for the technology (and weather
              cell) specified in `curtailment_key`.
          feedin_df : :pandas:`pandas.Series<series>`
              Feed-in time series in kW for all generators of type (and in
              weather cell) specified in `curtailment_key`.
          curtailment_key : :obj:`str` or :obj:`tuple` with :obj:`str`
              Technology (and weather cell) curtailment is given for.