Хабрахабр

Автоматическая визуализация python-кода. Часть третья: новые возможности графического представления кода

Ссылки на предыдущие части:

  • Часть первая — обсуждены блок-схемы, имеющиеся инструменты для работы с блок-схемами, а также все графические примитивы, необходимые для создания графического представления кода.
  • Часть вторая — обсуждены реализация ( выполнена, в основном, на Питоне) генерации графического представления кода, реализованная и планируемая функциональность, предлагаемый микро язык разметки.

Пример среды, поддерживающей такое графическое представление показан на картинке ниже.

image

Среда, поддерживающая графическое представление кода

В третьей части статьи речь пойдет о новых возможностях графического представления кода.

Мелочи

Со времени написания второй части был добавлен интерфейс для смены цветов, используемых для отображения графических примитивов и интерфейс для смены текста, демонстрируемого графическим примитивом. В обоих случаях интерфейс минималистичен и использует контекстное меню.

Контекстное меню выбранных графических элементов

В появившемся контекстном меню можно выбрать нужный пункт (доступность пунктов меню определяется динамически). Пользователь выбирает один или несколько примитивов и нажимает правую кнопку мыши.

После завершения ввода в исходный текст добавляются/модифицируются необходимые cml комментарии и вся диаграмма немедленно перерисовывается с учетом изменений. В случае выбора одного из первых двух пунктов меню демонстрируется дополнительный диалог для выбора цвета или ввода текста соответственно.

Подавление примитивов

В процессе работы со средой было замечено, что иногда возникает желание временно скрыть некоторые графические элементы с целью сократить количество представленной на экране информации. Это может помочь при определенных сценариях анализа программы. Разумеется, такую функциональность довольно просто реализовать для графического представления.

Для управления подавлением примитивов на панель инструментов графического представления добавлены три кнопки, каждая из которых может находиться в одном из двух положений: нажата/отжата. Были определены следующие кандидаты: строки документации, комментарии и блоки except.

Управление подавлением примитивов на диаграмме

По изменению состояния кнопок диаграмма немедленно перерисовывается, то есть буквально одним щелчком мыши можно оперативно изменить количество деталей, отображаемых в данный момент. Кнопки независимы друг от друга, таким образом можно выбрать любую требуемую комбинацию подавления.

Подавление строк документации

Питон поддерживает строки документации для модулей, классов и функций. Для отображения всех этих случаев Codimension использует примитив типа «область видимости», в котором после заголовка и располагается строка документации. Например:

Функция со строкой документации

Например: Однако строки документации не являются обязательными, и в случае, если разработчик не позаботился о документации, Codimension не рисует соответствующую секцию совсем.

Функция без строки документации

Поэтому было принято такое решение — вместо подавленных строк документации рисовать секцию, в которой вместо всего текста помещен только бэдж. Когда строки документации подавлены, можно было бы не рисовать секцию, но тогда невозможно было бы по взгляду на диаграмму понять: документации нет вообще или она подавлена. И позволяет легко добавить всплывающую подсказку для секции с полным текстом документации. Бэдж занимает меньше места, чем одна строка, дает возможность немедленно понять, что документация есть. Например:

Функция с подавленной строкой документации

В случаях, когда документация пространна, а первоначальное ознакомление с модулем уже закончено, функциональность подавления docstring представляется довольно удобной.

Подавление комментариев

Комментарии также могут отнимать существенное пространство на диаграмме. Иногда возникает желание подавить и их. Совсем не рисовать комментарии кажется неразумным по тем же соображениям, что и для строк документации, поэтому было принято решение заменять их на примитив небольшого размера, поддерживающий всплывающую подсказку с полным текстом комментария.

Комментарии показаны

Комментарии подавлены

Подавление блоков except

Обычно код, располагающийся в except блоках, не лежит на основном пути выполнения программы, а служит для обработки редких исключительных ситуаций. Поэтому при анализе основного назначения программы кажется удобным иметь возможность подавить блоки except и представить их небольшим примитивом, который дает понять, что они вообще есть.

Два показанных блока except

Подавленные блоки except

Во всплывающей подсказке к примитиву показываются столько строк, сколько было except блоков с указанием того, что перехватывается в каждом.

Умное масштабирование

Codimension в его нынешней реализации поддерживает два типа масштабирования диаграммы. Обычное, или просто масштабирование, которое основано на размере выбранного шрифта. При таком масштабировании размер шрифта увеличивается или уменьшается, а затем пересчитываются все размеры. Умное масштабирование предполагает несколько фиксированных уровней, на каждом из которых меняется содержимое диаграммы. Каждый следующий уровень скрывает все больше и больше элементов на диаграмме.

Для управления переключениями уровней на панели инструментов добавлен индикатор текущего уровня и кнопки перемещения вверх и вниз. Придумать разумные короткие названия для каждого из уровней не удалось, поэтому они обозначены цифрами.

Управление умным масштабированием

Для индикатора уровня добавлена всплывающая подсказка с описанием того, какие изменения сделаны на диаграмме.

То есть, если уровень предполагает показ, например, блоков except, то они могут быть независимо подавлены нажатием соответствующей кнопки. Умное масштабирование работает совместно с настройками подавления элементов. На примерах, приведенных ниже предполагается, что ни комментарии, ни строки документации, ни блоки except не подавлены.

Уровень 0

Это уровень максимальной детализации. Показаны все графические элементы.

Уровень 1

На этом уровне с диаграммы исчезают комментарии и строки документации. Остальные графические примитивы остаются на диаграмме, но текст в них подавлен, за исключением заголовков классов и функций.

Умное масштабирование: уровень 1

Для каждого графического элемента на этом уровне добавлена всплывающая подсказка, в которой показан подавленный текст. Такое представление позволяет быстро получить представление об объеме кода и его сложности: чем выше концентрация «коробочек» на диаграмме, тем сложнее код.

Уровень 2

На этом уровне на диаграмме остаются примитивы, использующие для отображения область видимости (за исключением декораторов) и условные конструкции. Такое представление также предназначено для быстрой оценки сложности. Фактически, на диаграмме остается вложенность и ветвления.

Умное масштабирование: уровень 2

Уровень 3

На этом уровне на диаграмме остаются только классы и функции. Такое отображение задумывалось как «взгляд с высоты птичьего полета», только крупные объекты в модуле остаются видимыми.

Умное масштабирование: уровень 3

Больше уровней

На данный момент опыт практического применения уровней умного масштабирования очень маленький. Поэтому сделать твердые выводы о полезности какого-либо из уровней, как и вообще идеи умного масштабирования, затруднительно. В планах, однако, есть введение следующего уровня с номером 4. На нем предполагается показать диаграмму зависимости модуля, своего рода взгляд на файловую систему. В центре может располагаться примитив текущего модуля, а вокруг него примитивы импортированных модулей. Таким образом появится возможность визуально оценить текущие зависимости.

На графическом представлении оказалось довольно просто манипулировать содержимым. Интересно, что реализация умного масштабирования не потребовала больших усилий. Поэтому введение каких-то новых промежуточных уровней в экспериментальных целях возможно выполнить очень быстро.

Группы

Основная идея функциональности проста — дать возможность объединять несколько графических элементов в группу, с последующим сворачиванием и разворачиванием группы в один графический элемент с новой подписью. Сценарий использования может быть, например, такой. Разработчик начинает работать с новым для него кодом, написанным другим человеком. В ходе анализа постепенно приходит понимание, что делает фрагмент кода, состоящий, скажем, из десяти блоков. Тогда разработчик объединяет эти блоки в группу и снабжает ее подходящим текстом. При дальнейшем анализе группа остается на экране свернутой, то есть на диаграмме вместо 10 элементов находится только один, что должно облегчить последующий анализ. Разумеется, группы могут быть вложенными и нет ограничений на количество групп в модуле.

Программист может создавать группы, что облегчит анализ кода тем, кто будет работать с ним впоследствии. Никто не запрещает использовать группы и в момент первоначальной разработки.

Первые два — это диаграмма, а третье — это свернутая группа, внутрь которой можно заглянуть. Так как группы поддерживают неограниченную вложенность, то их можно рассматривать как введение подобия третьего измерения в код.

CML для групп

Чтобы нарисовать группу на диаграмме, Codimension должен знать, где она начинается и где кончается. Чтобы оставить соответствующий отметки в коде, используется микро язык разметки в комментариях Codimension Markup Language.

# cml 1 gb id=101 title="Module imports"
import sys
import logging
import json
# cml 1 ge id=101

Первый комментарий имеет код gb (от слов group begin) и располагается перед первым элементом группы. Второй комментарий имеет код ge (от слов group end) и располагается после последнего элемента группы. Codimension понимает, что комментарии парные по значению обязательного атрибута id, который может быть произвольной строкой.

Группа должна иметь один вход и один выход. Очевидно, что для формирования группы есть ряд ограничений. Если выделено условие if, то все ветки также должны быть выделены. При выделении элементов для группы на графике, все они должны быть выделены без пропусков. Аналогично нельзя разрывать составные части try-except-else-finally. Для циклов похожее требование связано с конструкцией else: если она присутствует, то должны быть выделены обе части, и сам цикл и его else блок. Все эти ограничения учитываются, когда интерфейс пользователя разрешает выполнить группировку.

При первоначальном дизайне технологии было принято решение не поддерживать завершающие комментарии. Кроме того, по ходу работы над группами, потребовалось изменение в парсере питона. Например, группа может объединять все элементы в одной из веток if: Однако для групп такой завершающий комментарий совершенно необходим.

item = self.__processes[index]
if item.widget: # cml 1 gb id=102 title="Script started" msg = item.widget.appendIDEMessage('Script started') item.procWrapper.startTime = msg.timestamp # cml 1 ge id=102

Здесь завершающий группу комментарий должен принадлежать ветке if, что не было предусмотрено ранее.

Для этого в открывающем cml комментарии поддерживаются необязательные атрибуты для задания цветов фона, чернил и обводки. Для групп также добавлена возможность изменить цвета по умолчанию.

Графика для групп

Для отрисовки групп требуются три варианта примитивов: свернутая группа, раскрытая группа и пустая группа.

При этом также желательно, чтобы отрисовка примитива была простой независимо от того, выделен он или нет. Для свернутой группы желателен такой примитив, чтобы сразу было понятно, что за ним скрываются несколько элементов и что его можно раскрыть. В результате был выбран прямоугольник с двойной обводкой, внутри которого размещается заголовок группы.

Свернутая группа

Полного удовлетворения от выбранного примитива на данный момент нет, поэтому есть шанс, что он будет заменен на что-то другое в будущем.

Чтобы границы смотрелись «полегче», прямоугольник раскрытой группы нарисован пунктирной линией. Раскрытая группа должна обозначать свои границы, плюс должна быть возможность быстро посмотреть заголовок группы. Особенного смысла делать поля раскрытой группы широкими нет, поэтому пунктир нарисован ближе к примитивам, чем если бы это был другой элемент.

Раскрытая группа

Когда курсор мыши находится над ней, обводка группы рисуется сплошной линией, а над группой показывается ее заголовок. В левом верхнем углу раскрытой группы нарисована ее «чувствительная точка».

«Чувствительная точка» раскрытой группы

Это позволит выполнять действия с минимальным количеством щелчков кнопок мыши. В случае необходимости, в дополнение к заголовку группы, можно будет добавить и какие-нибудь кнопки управления.

В дальнейшем, когда появятся функции редактирования на графическом представлении, в пустую группу можно будет добавить новые элементы. В пустой группе ничего нет, но она может, к примеру, содержать заголовок. Для нее выбран прямоугольник с обводкой штрихом. Поэтому рисовать пустую группу все же надо.

Пустая группа

Поэтому, если для свернутой группы примитив будет изменен, то и для пустой группы должны быть сделаны соответствующие изменения. Очевидна похожесть примитивов пустой и свернутой групп.

Для создания группы выделяются нужные примитивы, а затем из контекстного меню выбирается пункт Group… После ввода заголовка группы нужные CML комментарии добавляются в код и диаграмма немедленно перерисовывается. Управление группами осуществляется из контекстного меню. При этом вновь созданная группа рисуется в свернутом виде.

Все остальные манипуляции с группами — раскрытие, скрытие, удаление, редактирование заголовка, смена цветов — выполняются по выбору из контекстного меню группы.

Как попробовать

Попробовать новую функциональность можно установив Codimension IDE. Codimension поддерживает Linux и Mac. Инструкции по установке доступны на codimension.org

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»