Нейросеть для работы с кодом: разобрать чужую функцию
Нейросеть для работы с кодом полезна не только тем, кто пишет программы. Как разобрать чужую функцию построчно, найти скрытую ошибку и понять, что улучшить.
А
Андрей
Преподаватель, научный редактор LibraChat
7 мин чтения
Тебе достался чужой код, и ты не понимаешь, что он делает? Со мной это случилось на работе. Сотрудник, который вёл сайт нашего журнала, уволился и оставил функцию в одну строку без единого комментария. Мне нужно было понять, что она делает, прежде чем что-то трогать. Нейросеть для работы с кодом объяснила её построчно, нашла ошибку, о которой никто не знал, и предложила понятную версию. Ниже вопросы, которые я задавал себе по ходу, запрос в LibraChat и ответ, который я разобрал как преподаватель.
Зачем нейросеть для работы с кодом тому, кто не программирует?
Я научный редактор. Программировать учусь недавно, на Python. А функция на сайте была на JavaScript, языке, которого я не знаю. Вот она, целиком:
```javascript
function f(a){let r=[];for(let i=0;i<a.length;i++){if(a[i]%2==0&&r.indexOf(a[i])==-1)r.push(a[i])}return r.sort()}
```
Одна строка. Однобуквенные имена. Ни слова пояснения. Я смотрел на неё минут десять и понял только слово `return`. Программисты называют такой код «чужим», даже когда автор сидит за соседним столом.
Мне не нужно было его переписывать. Каюсь, первой мыслью было просто удалить функцию и посмотреть, что сломается. Так поступают отчаявшиеся студенты с непонятными абзацами в курсовой. Но сайт журнала читают тысячи людей, и проверять «на живых» мне не хотелось. Мне нужно было понять, что он делает, чтобы ответить на вопрос коллеги: «Можно ли эту штуку удалить?»
Как спросить, чтобы объяснение было понятным?
Я написал запрос так, как попросил бы коллегу-программиста объяснить мне что-то за чаем:
Объясни мне этот код на JavaScript построчно, как новичку, и скажи, что в нём можно улучшить: function f(a){let r=[];for(let i=0;i<a.length;i++){if(a[i]%2==0&&r.indexOf(a[i])==-1)r.push(a[i])}return r.sort()}
В запросе три просьбы. Построчно. Как новичку. И что улучшить. Каждая работает на свою задачу: первая даёт структуру, вторая задаёт уровень, третья превращает объяснение в разбор.
Что делает этот код: нейросеть для работы с кодом объясняет по строкам
Ответ начался с одной фразы, которую я и искал:
Этот код берёт массив и возвращает уникальные чётные числа из него, отсортированные.
Дальше LibraChat переписал функцию с переносами строк, и она сразу стала читаемой. А потом разобрал каждую строку. Вот как я свёл разбор для себя:
Строка · Что делает, по ответу
`function f(a)` — функция с одним аргументом; по смыслу это массив чисел, но это не проверяется
`let r = []` — пустой массив, куда складываются подходящие числа
цикл `for` — перебирает все элементы по очереди
`a[i] % 2 == 0` — число чётное: остаток от деления на 2 равен нулю
`r.indexOf(a[i]) == -1` — этого числа ещё нет в результате
`r.push(a[i])` — добавляет число в конец
`return r.sort()` — сортирует и возвращает результат
И пример, который сделал всё наглядным: из массива `[5, 2, 8, 2, 3, 4]` функция возвращает `[2, 4, 8]`. Нечётные ушли, повторная двойка ушла, остальное по порядку.
Отдельно мне понравилось, как объяснено условие из двух частей. В ответе прямо сказано, какие числа проходят проверку на чётность: 2, 0 и −4 проходят, 3 и 2.5 нет. Такие примеры с граничными случаями я сам даю студентам, когда объясняю правило. Ноль и отрицательные числа обычно забывают первыми.
Как преподаватель я оценил, что объяснение шло от целого к частям. Сначала «что делает», потом «как». Именно так я сам объясняю студентам сложные тексты: сначала тезис, потом аргументы.
А что в нём не так?
Здесь была главная находка. Первым пунктом раздела «Что стоит улучшить» стояло:
Сортировка без правила сравнения работает неправильно. Без функции сравнения sort() сравнивает элементы как строки.
И пример: массив `[10, 2, 4]` после такой сортировки останется `[10, 2, 4]`, а не станет `[2, 4, 10]`. Потому что как строки «10» идёт раньше «2».
Я проверил это в консоли браузера. Так и есть. А на сайте эта функция сортировала номера выпусков журнала. Выпуски с 10-го по 19-й в списке стояли перед вторым. Мы года три думали, что это особенность вёрстки. Никто не связывал странный порядок выпусков с одной строкой кода, которую давно никто не открывал.
Остальные пункты разбора были про качество, а не про ошибки:
поиск дубликатов через `indexOf` на большом массиве медленный, лучше специальная структура `Set`;
имена `f`, `a`, `r` ничего не говорят;
нет проверки, что на вход пришёл массив чисел.
Как выглядит исправленная версия?
В ответе была переписанная функция: с говорящим именем `uniqueEvens`, с `Set` для уникальности, с проверкой, что число целое, и с правильной числовой сортировкой. И пояснение: порядок появления сохраняется так же, как в исходном коде, до сортировки.
Новую версию я не стал ставить на сайт сам. Отдал знакомому разработчику вместе с объяснением из ответа. Он прочитал и сказал: «Всё верно, только проверь, что номера выпусков у вас точно числа, а не строки». Хороший совет: если номера хранятся строками, новая проверка на целое число их отсеет. Это именно то, чего нейросеть знать не могла: она видела функцию, но не видела наших данных. Разработчик видел и то, и другое. Мы проверили, номера были числами.
Что делать, если кода много?
Одна функция в строку — простой случай. Через неделю мне достался целый файл того же сотрудника, около 300 строк. Вставлять его целиком и просить «объясни всё» я не стал. Сначала я попробовал так и сделать на старом файле из учебника и сам утонул: объяснение было верным, но охватывало всё сразу, и я не понял, с чего начать.
Теперь у меня порядок как при чтении трудной монографии:
Сначала прошу сказать в двух-трёх фразах, что делает файл целиком.
Потом прошу перечислить функции и одной строкой описать каждую.
Потом разбираю по одной функции, той, что меня интересует, построчно.
Всё это в одном чате, чтобы не объяснять заново, о каком файле речь.
Куски по 40–50 строк читаются хорошо. Больше — объяснение начинает скользить по верхам, как мой студент, который пересказывает главу, не дочитав её.
Отдельное правило я взял из редактуры. Если в коде есть место, которое кажется странным, спрашиваю именно про него, отдельным сообщением. «Почему здесь сравнение через два знака равенства, а не через три?» Такие вопросы дают самые полезные ответы, потому что за ними обычно прячется либо ошибка, либо чьё-то осознанное решение.
Можно ли доверять объяснению?
Можно, но проверять. Я сделал две вещи, и советую их каждому:
Запустил исходную функцию на примере из ответа и сравнил результат. Совпало.
Проверил главное утверждение про сортировку на своём маленьком массиве. Тоже совпало.
Это 5 минут в консоли браузера. Для объяснения, на основании которого ты будешь что-то менять на работающем сайте, это немного.
И граница. Нейросеть объясняет код, который ты ей показал. Она не знает, откуда эта функция вызывается, какие данные в неё приходят на самом деле и что сломается, если её убрать. Это знаешь ты или человек, который отвечает за систему.
Чему меня научила нейросеть для работы с кодом на одной функции?
Больше, чем за неделю учебника. Я теперь знаю, что `%` в JavaScript работает как в Python, что `sort()` без аргументов сравнивает строки, и что однобуквенные имена — это вежливая форма ненависти к будущему читателю кода.
Если ты пишешь код каждый день и тебе интересно, как нейросеть помогает именно программисту, есть статья нейросеть для программиста.
Попробуй на своём куске кода
Маленькое задание. Найди функцию, которую ты не понимаешь: на работе, в учебнике, в чужом проекте. Открой чат LibraChat и вставь её вместе с тремя просьбами: построчно, как новичку, что улучшить. Потом проверь одно утверждение из ответа сам. Разбор одной функции можно сделать бесплатно, а возможности платных тарифов описаны на странице тарифов.
нейросеть для работы с кодомjavascriptразбор кодачужой кодучёбасамообучение