Best tools no one uses: DOT (овалы со стрелками)

Иногда при копании в текстовых файлах, в которых хранится дерево зависимостей или граф, хочется получить наглядное представление этого файла.  Это могут быть зависимости между данными или промежуточное состояние программы при отладке сложного алгоритма на графе/дереве.
Есть простой инструмент, DOT language, который по текстовому файлу сгенерирует рисунок.
Например, по описанию

digraph graphname {
  a -> b -> c;
  b -> d;
}

будет построен рисунок:


Вот больше картинок для иллюстрации: http://www.graphviz.org/Gallery.php
Позволяет просто делать простые вещи, не вникая в детали. Имеет достаточную гибкость для того что бы делать сложные схемы с кучей подсказок и заданных ограничений.
Если в схеме меньше двадцати стрелочек, то получается что-то наглядное и полезное для понимания/отладки. Если сильно больше – то схема скорее только запутает, надо думать как отрезать незначительные детали. Например, схема вложения #include-файлов в большом C++проекте будет похожа на дельту Миссисипи при наводнении.  А вот зависимости между подсистемами целиком – вполне наглядны.  Или зависимости в пределах одной подсистемы. Схему всех квестов (500 штук) в игре – просмотреть невозможно. А схемы квестов для конкретных сюжетов – вполне реально.
Файлы такие конечно пишутся не руками, их лучше генерировать из отлаживаемой программы по ключу командной строки.
Пример генерации графа, который показывает, как числа друг на друга делятся:
print 'digraph {'
for n in range(1, 50):
  for k in range(1, n):
    if n % k == 0:
      print '%d -> %d' % (n, k)
print '}'

Генерация из командной строки происходит так:
python gen_numbers.py | tred | dot -Tpng -oout.png
Здесь так же использован упроститель графа tred, который убирает избыточные стрелки в графе зависимостей (если 12 -> 6 -> 3, то не надо отображать стрелку 12 -> 3).
Взять DOT можно вот здесь: http://www.graphviz.org/

  • kas

    забавно, спасибо!