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 иногда создает хороший код. Но это не надежно