«Увлекательное испытание себя» – так описывают студенты участие в хакатоне, который проходит каждый семестр у первокурсников магистерской программы JetBrains&ITMO. DevDays – это три дня и три ночи интенсивной работы и горячих митингов, знакомство с новыми технологиями и множество строк кода. Ребята работают в небольших командах и проходят все этапы разработки: от возникновения идеи проекта до работающего решения. А прошедшей весной студенты наконец поработали друг с другом вживую после почти года удаленки.
В этом посте рассказываем подробнее об идеях проектов: два плагина для Intellij IDEA, приложение для тиктокеров, эмулятор мыши для механических клавиатур и чатбот-органайзер.
Capture the Ownership
Автор идеи: Кирилл Бочкарев
Участники проекта: Кирилл Бочкарев, Кирилл Есаков и Егор Елисеев
Задача этого проекта – сделать плагин для Intellij IDEA, который позволит автоматически приписывать файлам в репозитории их владельцев. Владение определяется по времени, который разработчик провел в файле. Это может помочь в оценке рисков проекта, в поиске тех, кто может исправить возникшие ошибки, или тех, кто может объяснить смысл написанного. Такое решение сделает владение более прозрачным и частично-управляемым.
Самый популярный и очевидный способ поиска разработчиков, знакомых с конкретными файлами – это работа с данными Git (например, вот, вот или просто Git blame). Из очевидных недостатков:
учитывается только прямое участие в написании кода;
внесение чисто стилистических изменений в код может сделать владельцем файла неочевидного человека;
трудно определить владельца файла, который за короткое время изменяет несколько человек.
При выборе основного языка реализации мы рассматривали Java и Kotlin. Остановились на Kotlin, потому что казалось, что на нём будет проще писать код. Но мы всё равно столкнулись с NullPointerException’ами. Кстати, для плагинов IDEA есть прекрасный репозиторий-шаблон, который решил почти все вопросы за нас.
Для хранения данных у пользователей мы выбрали XML как наиболее простой способ передавать сохраненную информацию о владении файлами. В качестве альтернативы рассматривали базы данных, в том числе MongoDB. Они могли бы улучшить производительность, но это пока было излишним. База данных может понадобиться, если продумать работу при полноценном версионировании репозитория: переключение коммитов, слияние веток.
У нас получилось разбить проект на три независимых модуля: реагирование на события внутри IDEA, подсчет времени и его хранение. Каждый модуль успешно писал один человек, а в конце было достаточно написать несколько вызовов одного из другого, и всё заработало.
Мы сформулировали две гипотезы, на которых основывалось наше решение:
в файлах лучше разбираются те, кто проводят в них много времени;
время можно делить на «горячее» (редактирование кода) и «холодное» (чтение), при этом первое важнее второго в X раз.
К сожалению, мы не смогли подтвердить эти гипотезы никакими конкретными исследованиями.
Плагин получился недостаточно производительным: он реагирует почти на любую активность внутри редактора IDEA. В процессе работы мы также поняли, что не каждый разработчик захочет делиться временем, которое он проводит в каждом файле – это похоже на слежку. Поэтому в общем доступе было решено хранить только время владельцев файлов, но даже это может многим не понравиться.
Взаимодействие с системами контроля версий мы не до конца продумали даже в теории. Например, если в двух ветках разработки у файла разные владельцы, то определить владельца при слиянии будет проблематично.
К концу хакатона у нас получилось сделать плагин для IDEA, который считает время, проведённое разработчиком при редактировании и просматривании файлов. Просмотр учитывается как «холодное» время, оно ценится в два раза меньше «горячего». «Горячее» – это редактирование, причем оно «греет» еще семь секунд после себя (т.е. ко времени редактирования добавляется еще семь секунд). В общем доступе хранится файл с указанными для файлов владельцами. Когда личное время разработчика превышает время текущего владельца, разработчику предлагается забрать владение файлом себе. Если разработчик соглашается, то он становится владельцем файла, и его время по этому файлу становится доступно всем участникам проекта.
Plama
Авторы идеи: Евгений Слободкин и Арсений Терехов
Участники проекта: Евгений Слободкин, Арсений Терехов, Сергей Сокольвяк и Николай Егоров
На магистерской программе читается курс по языками программирования и компиляторам, на котором студенты работают с языком программирования Lama. Хотя Lama является по большей части учебной, это вполне полноценный язык программирования, вдохновленный такими функциональными языками как Haskell и OCaml. В нем функции являются объектами первого класса, есть сборщик мусора, есть S-выражения, напоминающие алгебраические типы данных, есть сопоставления с образцом и много что ещё.
При знакомстве с этим языком хочется иметь какую-то поддержку со стороны инструментов разработки, например, плагин для IntelliJ IDEA. Это и стало идеей для проекта на хакатоне. Мотивацию ещё подогревал тот факт, что можно сделать что-то полезное не только для нас, но и для других ребят, которые будут проходить курс в будущем.
Конечно, мы не первые, кто сталкивается с желанием инструментальной поддержки этого языка. Есть и другие решения. Например, мы нашли два хороших плагина для VSCode. Однако язык с момента их публикации изменился, и теперь, к сожалению, на некоторых конструкциях языка плагины работают некорректно. К тому же не все хотят устанавливать себе VSCode исключительно ради одного курса, в то время как IntelliJ IDEA пользуются большинство студентов.
Когда люди начинают писать на новом, незнакомом для них языке, основной сложностью для них является незнание базовых синтаксических конструкций. Среда разработки, в свою очередь, помогает справиться с этим с помощью подсветки синтаксиса и сообщений об ошибках. Поэтому перед началом работы мы выделили базовую функциональность, которую должен поддерживать наш плагин:
хорошая подсветка синтаксиса
человекочитаемые сообщения о синтаксических ошибках
Также мы хотели поддержать и более продвинутую функциональность, к которой все уже давно привыкли:
автодополнение кода
навигация по коду (переход к определению функций/переменных)
После выделения функциональности разработка плагина разделилась на основные подзадачи: нужно было создать основную инфраструктуру плагина, реализовать парсер языка и разработать модуль, отображающий всё в GUI.
Каждый выбрал себе по задаче, и работа началась. Так как мы разрабатывали плагин для IntelliJ IDEA, долго выбирать технологии не пришлось – для реализации мы использовали IntelliJ Platform Plugin SDK. В частности, парсер языка Lama для плагина был написан с помощью Jetbrains Grammar Kit. В ходе работы оказалось, что Grammar Kit далеко не самый удобный парсер генераторов, однако его значительное преимущество заключается в генерации парсера, совместимого с IntelliJ Platform по интерфейсам.
По завершению хакатона у нас получилось поддержать всю базовую функциональность и поработать над более продвинутой. Так, наш плагин позволяет IDEA распознавать файлы с кодом на Lama, красиво подсвечивать в них синтаксис и сообщать пользователям информацию о синтаксических ошибках в человекочитаемом виде. Более того, у нас поддерживается code completion встроенных библиотечных методов, что позволяет быстро находить нужные библиотечные функции.
Но навигацию в полной мере реализовать так и не удалось: много времени и сил ушло на создание инфраструктуры ссылок и работу с документацией, а навигация по коду пока не поддерживается со стороны GUI. Будем дорабатывать!
TikFake
Автор идеи: Леденева Екатерина
Участники проекта: Клочков Антон, Леденева Екатерина, Деркунский Виктор и Тлямов Анвар
Идея проекта – клонировать движения человека на видео из TikTok с помощью виртуального персонажа. Это идея just for fun. Она не несет особого смысла, не решает каких-то проблем. Приложение просто дает возможность развлечься и немного посмеяться.
Материалов, посвященных генерации виртуальных персонажей (то есть таких, которые повторяют движения исходного человека), много. Например, вот один из них. В этой работе авторы продемонстрировали, как можно с помощью глубоких нейронных сетей проецировать записанные человеком движения на других персонажей. Для этого они извлекают дескрипторы движения и оптический поток (по сути, смещение кадров) и применяют их к виртуальному персонажу. Но так как у нас не было вычислительных мощностей и наборов данных, то подобные решения на основе глубокого обучения отпадали.
Тогда к нам пришла идея использовать фреймворк Mediapipe, а точнее инструмент для извлечения скелета человека, с которым у одного из членов команды был опыт работы. Изначально мы хотели реализовать наложение скелета на 3D-модель, но т.к. из ресурсов была только обычная web-камера, мы не смогли бы найти глубину точек, поэтому остановились на 2D-варианте.
Стек технологий проекта:
Python — отличный язык для прототипирования, у всех членов команды был опыт работы с ним;
Mediapipe — хороший опыт работы у одного из участников команды; надёжное решение от Google;
OpenCV — использовали для захвата изображения с камеры, отрисовки объектов и отображения на экране устройства.
В итоге получилось приложение, которое по ссылке на видео из TikTok создаёт новое видео с (предварительно подготовленной) 2D-моделью, повторяющей движения человека из оригинала. Также была создана дополнительная версия приложения с повторением действий человека с web-камеры (основные компоненты решения не зависят от формата исходного видеоряда, поэтому добавить такую версию оказалось легко).
К проблемам во время разработки можно отнести то, что не у всех участников был опыт работы с OpenCV – приходилось разбираться на ходу. Также TikTok не имеет внятного API, поэтому приходилось очень долго искать информацию, как скачивать контент в автоматическом режиме.
Мыши и Зефир
Автор идеи: Александр Крикун
Участники проекта: Александр Крикун, Дмитрий Цыкунов
Во время представления идей проектов Александр предложил добавить возможность эмуляции мыши для механических клавиатур в прошивку ZMK. Саша говорил такие крутые фразочки, как «RTOS», «чистый С», махал беспроводными, странными на вид, клавиатурами и приговаривал «контрибьютим в опенсорс», «давайте паять». Дмитрий понял, что с этим человеком на одной волне и захотел поучаствовать в его проекте.
Существует другая прошивка – QMK, в которой разрабатываемая фича есть, но она не поддерживает беспроводные технологии, за которыми, как известно, будущее. Нам хотелась добавить такую же возможность, но уже полноценную, к прошивке ZMK. Из-за особенностей лицензирования проектов использовать код QMK было нельзя, и разработка велась по сути «с нуля»: мы использовали только документацию протокола USB HID и сниффинг трафика с реальной мыши.
Стек технологий выбирать не приходилось – это RTOS Zephyr. Расширяемый проект использует именно эту ОС. Код ZMK написан на C. Разобраться в кодовой базе проекта больше всего мешали макросы. Макросы, вложенные в другие макросы. Голова кругом шла!
Для того, чтобы клавиатура работала как мышь, она должна вести себя как мышь. Для этого мы научили ZMK вдобавок к существующим структурам отдавать структуру HID-репорта, неотличимую от любой современной мыши. Затем добавили возможность посылать с клавиш корректные репорты под эту структуру – клики (вплоть до 16 клавиш), движение, скролл (горизонтальный и вертикальный).
В итоге нам удалось заставить мышку кликать и двигаться. Все наработки Александр оформил в пулл-реквест в официальный проект ZMK на Github. Он находится на стадии обсуждения с официальными разработчиками. В дальнейшем этот код можно использовать как базу для поддержки трекпоинтов и т.д.
Чатбот-ораганайзер
Автор идеи: Дмитрий Иванов
Участники проекта: Дмитрий Иванов, Тигран Акопян, Екатерина Дедученко и Максим Ефимов
В процессе учёбы студенту приходится иметь дело со множеством ссылок. Например, ссылки на расписание или домашние задания, которые регулярно меняются и ведут на различные ресурсы (wiki или Google Drive). Появилась идея объединить информацию для простого и быстрого поиска. Мы решили сделать это в виде чат-бота в Telegram.
Библиотеки для написания чат-ботов в Telegram есть почти во всех языках программирования. Поэтому основным языком по желанию команды мы выбрали Kotlin. Аналогично, back-end также можно было реализовать на любом языке, и выбор пал на Java. Для хранения данных на back-end была выбрана СУБД SQLite из-за своей простоты.
Задачу разделили на две: чат-бот (front-end), который делал запросы к веб-серверу (back-end), где хранились данные о расписании, домашних заданиях и прочем. Над каждой задачей работали два человека. Хочется отдельно отметить возможность использования Code With Me в IDE от JetBrains – стандартный способ разработки командой через Git-flow (пулл-реквесты) выглядит слишком медленным и ограничивающим, когда речь идет о хакатонах.
Задачи проекта довольно простые и понятные, поэтому с самой разработкой проблем никаких не возникало. Была лишь сложность в координации: один из участников проекта находился не в Петербурге, и большая разница в часовых поясах усложняла взаимодействие.
Практически все задачи, поставленные перед стартом хакатона, были реализованы. Но для быстрого результата, к сожалению, иногда нам приходилось жертвовать качеством кода.
Возможности бота:
получить расписание занятий на неделю или на любой день недели с учётом группы;
получить все домашние задания на неделю с учётом группы;
получить домашнее задание по какому-то определённому предмету;
посмотреть ближайшие дедлайны;
отправить домашнее задание преподавателю на почту;
получить ссылку на Google-таблицу с успеваемостью по данному предмету.
До 9 августа продолжается прием документов на корпоративную магистерскую программу JetBrains «Разработка программного обеспечения». В этом году набор ведется на 30 бюджетных и 5 платных мест. Подробнее о программе можно узнать на сайте или в Telegram-чате для абитуриентов.