<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _precheck(self, curtailment_timeseries, feedin_df, curtailment_key):
 """ 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. """

        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)