<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _df(self, x, user_data=None):
 """ Evaluates the cost gradient. """

        p_gen = x[self._Pg.i1:self._Pg.iN + 1] # Active generation in p.u.
        q_gen = x[self._Qg.i1:self._Qg.iN + 1] # Reactive generation in p.u.

        # Polynomial cost of P and Q.
        xx = r_[p_gen, q_gen] * self._base_mva

        iPg = range(self._Pg.i1, self._Pg.iN + 1)
        iQg = range(self._Qg.i1, self._Qg.iN + 1)

        # Polynomial cost of P and Q.
        df_dPgQg = zeros((2 * self._ng, 1))        # w.r.t p.u. Pg and Qg
#            df_dPgQg[ipol] = matrix([g.poly_cost(xx[i], 1) for g in gpol])
#            for i, g in enumerate(gn):
#                der = polyder(list(g.p_cost))
#                df_dPgQg[i] = polyval(der, xx[i]) * base_mva
        for i in self._ipol:
            p_cost = list(self._gn[i].p_cost)
            df_dPgQg[i] = \
                self._base_mva * polyval(polyder(p_cost), xx[i])

        df = zeros((self._nxyz, 1))
        df[iPg] = df_dPgQg[:self._ng]
        df[iQg] = df_dPgQg[self._ng:self._ng + self._ng]

        # Piecewise linear cost of P and Q.
        df = df + self._ccost.T
        # TODO: Generalised cost term.

        return asarray(df).flatten()