CoPilot не представляет угрозы для хорошего программиста

Требования: некоторые знания Python и C++.

Много говорят о ChatGPT. Но самым старшим в округе является Github CoPilot. Я попросил CoPilot рассчитать внутреннюю норму доходности, используя комментарий:
Рассчитать внутреннюю норму доходности ряда денежных потоков (irr)

Последняя фраза «(irr)» была сгенерирована VSCode с помощью CoPilot (CP), я полагаю. Это само по себе было довольно впечатляюще. Я получил CoPilot для создания кода на C++ и Python. За три дня он сгенерировал три разные функции C++; только один из которых был правильным, как показано ниже:

/*
Compute the net present value of a series of cash flows npv
*/
double npv(double *cashflows, int n, double r)
{
    double npv = 0.0;
    double r1 = 1.0;
    for (int i = 0; i < n; i++)
    {
        npv += cashflows[i] / r1;
        r1 = r1 * (1.0 + r);
    }
    return npv;
}
/*
Compute the internal rate of return of a series of cash flows  (irr)
*/
double irr(double *cashflows, int n)
{
    double x0, x1, f0, f1, df;
    int i;
    x0 = 0.0;
    f0 = 0.0;
    for (i = 0; i < n; i++) {
        f0 += cashflows[i] ;
    }
    x1 = 0.1;
    f1 = npv(cashflows, n, x1  );
    while (fabs(f1) > 1.0e-6)
    {
        df = (f1 - f0) / (x1 - x0);
        x0 = x1;
        f0 = f1;
        x1 = x0 - f0 / df;
        f1 = npv(cashflows, n, x1  );
    }
    return x1;
}

Я заставил CoPilot сгенерировать npv и провел рефакторинг irr для его использования. Из двух других неправильных кодов один явно неправильный. Вот версия, сгенерированная CoPilot

/*
 Compute the net present value of a series of cash flows
*/
double npv(std::vector<double>& cashFlows, double discountRate) {
    double npv = 0.0;
    for (int i = 0; i < cashFlows.size(); i++) {
        npv += cashFlows[i] / std::pow(1 + discountRate, i);
    }
    return npv;
}
/*
Compute the internal rate of return of a series of cash flows  (irr)
*/
double irr(std::vector<double>& cashFlows) {
    double guess = 0.1;
    double npv = 0.0;
    double epsilon = 0.0000001;
    while (true) {
        npv = 0.0;
        for (int i = 0; i < cashFlows.size(); i++) {
            npv += cashFlows[i] / std::pow(1 + guess, i);
        }
        if (std::abs(npv) < epsilon) {
            break;
        }
        guess += 0.0001;
    }
    return guess;
}

Обратите внимание, что at npv может быть оптимизирован для предыдущей версии. По крайней мере, функция является отправной точкой в ​​том смысле, что ее можно настроить для вычисления значения большую часть времени. Третья версия, которую я не мог понять:

/*
Compute the internal rate of return of a series of cash flows  (irr)
*/
double irr(const std::vector<double>& cashflows, double guess)
{
    double x1 = guess;
    double x0 = 0.0;
    double f1 = 0.0;
    double f0 = 0.0;
    int max_iter = 100;
    int iter = 0;
    double eps = 1e-6;
    double dx = 1e-6;
    double df = 0.0;
    double f = 0.0;
    double x = 0.0;
    int i = 0;
    int n = cashflows.size();
    while (iter < max_iter)
    {
        f1 = 0.0;
        f0 = 0.0;
        for (i = 0; i < n; i++)
        {
            f1 += cashflows[i] / pow(1.0 + x1, i);
            f0 += cashflows[i] / pow(1.0 + x0, i);
        }
        df = (f1 - f0) / dx;
        f = f1 + (x1 - x0) * f1 / df;
        x = x1 - f1 / df;
        if (fabs(f) < eps)
        {
            break;
        }
        x0 = x1;
        x1 = x;
        iter++;
    }
    return x;
}

Первая версия Python была плоха тем, что обычно не сходилась:

"""
 Compute the net present value of a series of cash flows
 """
def npv(cashflows, rate):
     npv = 0.0
     for i in range(len(cashflows)):
         npv += cashflows[i]/(1+rate)**i
     return npv

"""
Compute the internal rate of return of a series of cash flows  (irr)
"""
def irr(cashflows):
    rate = 1.0/8
    def redeem(rate):
        return npv(cashflows, rate)
    redeem_value = redeem(rate)
    increment = 1.0/4096.0

    print("r=", rate)
    print("i=", increment)
    while abs(redeem_value) > 0.01:
        if redeem_value < 0 :
            rate = rate + increment
        else:
            rate = rate - increment
        redeem_value = redeem(rate)
        #print("r=", rate)
    return rate

Вторая версия, однако, является идеальной однострочной:

def irr(cashflows):
    return np.irr(cashflows)

Я не знал, что у Numpy есть такая встроенная функция.

В общем, CoPilot иногда создает хороший код. Но это не надежно