DRAKON.SU

Текущее время: Вторник, 19 Март, 2024 12:39

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 107 ]  На страницу 1, 2, 3, 4, 5, 6  След.
Автор Сообщение
СообщениеДобавлено: Среда, 02 Октябрь, 2019 22:47 
Аватара пользователя

Зарегистрирован: Вторник, 04 Октябрь, 2011 17:45
Сообщения: 585
Польза ДРАКОНа особенно очевидна в тех алгоритмах, где задаётся несколько вопросов.
Алгоритм со многими вопросами соответствует программе с вложенными конструкциями if.

Если в алгоритме есть хотя бы одна конструкция if, то, скорее всего,
ДРАКОН сделает алгоритм легче для понимания.
Если в алгоритме есть две или более конструкции if, то преимущества ДРАКОНа несомненны.
Возможность пальцем (взглядом) проследить все пути через алгоритм дорогого стоит.

Рассмотрим пример из реальной жизни.
Вот алгоритм InputBox_ok из исходного кода drakon.tech.
Этот алгоритм описывает реакцию на нажатие кнопки Ok диалога ввода текста.

Если в диалоге задана процедура проверки ввода (dialog.check), то эту процедуру следует запустить.
В случае, если процедура проверки вернула непустое сообщение (message), это означает, что обнаружена ошибка,
о которой надо сообщить пользователю.
Иначе следует послать введённое сообщение процессу, который создал диалог, и уничтожить диалог.
Вот ДРАКОН-схема:
Вложение:
20190920135601.png
20190920135601.png [ 137.24 КБ | Просмотров: 12711 ]

А вот эквивалентный ей код:
Код:
function InputBox_ok() {
    var dialog, message, value;
    dialog = module.dialog
    value = dialog.input.value
    if (dialog.check) {
        message = dialog.check(value)
        if (message) {
            InputBox_showError(dialog, message)
        } else {
            sm.sendMessage(
                dialog.scenario,
                "onResult",
                {text: value}
            )
            destroyPopup()
        }
    } else {
        sm.sendMessage(
            dialog.scenario,
            "onResult",
            {text: value}
        )
        destroyPopup()
    }
}


Главная проблема текстового представления - найти следующий шаг алгоритма при выходе из нескольких вложенных блоков.
В данном примере нужно поработать глазами, чтобы найти следующий шаг после первого destroyPopup().
ДРАКОН же выкладывает всё как есть, нужно просто идти вниз по линиям.

Ещё один недостаток текста - повторы. Конечно, опытный программист найдёт способ избежания повторов для данной функции,
но плюс ДРАКОНа в том, что нам больше не нужно заморачивать себе голову такими искусственными проблемами.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 02 Октябрь, 2019 22:53 
Аватара пользователя

Зарегистрирован: Вторник, 04 Октябрь, 2011 17:45
Сообщения: 585
А вот другой пример, тоже из реальной жизни.

Задача: отсортировать список объектов сначала по группе (поле sortGroup),
а потом по полю text, причём не взирая на регистр.
Сортировку делает функция Array.sort(), которая принимает функцию, которая сравнивает два элемента.
Вот ДРАКОН-схема:
Вложение:
20190920135812.png
20190920135812.png [ 137.35 КБ | Просмотров: 12710 ]


А вот текстовая программа:
Код:
function treeItemComparer(left, right) {
    var leftSortGroup, leftText, rightSortGroup, rightText;
    leftSortGroup = left.sortGroup
    rightSortGroup = right.sortGroup
    if (leftSortGroup === rightSortGroup) {
        leftText = left.text.toLowerCase()
        rightText = right.text.toLowerCase()
        if (leftText < rightText) {
            return -1
        } else {
            return 1
        }
    } else {
        if (leftSortGroup < rightSortGroup) {
            return -1
        } else {
            return 1
        }
    }
}


ДРАКОН-схема чётко показывает все четыре возможных случая, а также их взаимосвязь (главное - сравнить по sortGroup, а потом уж по text).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 02 Октябрь, 2019 23:07 
Аватара пользователя

Зарегистрирован: Вторник, 04 Октябрь, 2011 17:45
Сообщения: 585
Продолжаем разбор реальных, а не придуманных для презентаций алгоритмов.

Есть такой виджет - TreeView.
Это сложный виджет с хитрым поведением. Рассмотрим алгоритм реакции виджета на щелчок мыши по элементу дерева.
- Нам интересны щелчки только левой кнопкой мыши.
- Если не так давно уже был щелчок, то это двойной щелчок.
- Если виджет находится в процессе раскрытия узлов, мы игнорируем одинарный щелчок, но обработку двойного щелчка
откладываем на потом.
- Особо обрабатываются щелчки с нажатой клавишей Ctrl.
- Для узлов, которые могут иметь дочерние узлы, мы
        1. выделяем узел,
        2. начинаем процесс раскрытия узла (это дело долгое).

Все эти правила помещаются на одной ДРАКОН-схеме.
Вложение:
20190920135719.png
20190920135719.png [ 343.26 КБ | Просмотров: 12710 ]

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

Вот код:
Код:
function Tree_itemClick(machine, item, event) {
    var now;
    if (event.button === 0) {
        now = getUnixTime()
        if ((!(item.lastClick)) || (now - item.lastClick > DoubleClickThreshold)) {
            if (machine.state === "expanding") {
            } else {
                item.lastClick = now
                if (event.ctrlKey) {
                    Tree_ctrlClick(machine, item)
                } else {
                    if (item.leaf) {
                        Tree_singleClick(machine, item, event)
                    } else {
                        Tree_clearSelection(machine)
                        Tree_selectItem(machine, item)
                        Tree_toggleExpand(machine, item, event)
                    }
                }
            }
        } else {
            if (machine.state === "expanding") {
                machine.postponedDClick = item.id
            } else {
                Tree_doubleClick(machine, item, event)
            }
        }
    }
}



В этой "ёлочке" чёрт ногу сломит. Верните мне ДРАКОН.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 02 Октябрь, 2019 23:16 
Аватара пользователя

Зарегистрирован: Вторник, 04 Октябрь, 2011 17:45
Сообщения: 585
Это пример из игры Tetris
https://drakon.tech/js/examples/tetris

Данных алгоритм описывает реакцию на нажатие пальцем на игровом стакане.
Код:
function onGlassTap(evt) {
    var canvasPos, gamePos, touch;
    if (module.projectile) {
        touch = evt.touches[0]
        canvasPos = toElement(
            module.canvas,
            touch
        )
        gamePos = toGame(canvasPos)
        if (isLeftRegion(gamePos)) {
            onLeft()
        } else {
            if (isRightRegion(gamePos)) {
                onRight()
            } else {
                if (hitProjectile(gamePos)) {
                    onRotate()
                }
            }
        }
    }
}


Снова противная "ёлочка" из фигурных скобок. Вовсе не бросается в глаза, что сразу после onLeft(), onRight() и onRotate() происходит выход из алгоритма!

Но это очевидно на ДРАКОН-схеме:
Вложение:
20190920141005.png
20190920141005.png [ 173.77 КБ | Просмотров: 12710 ]

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 02 Октябрь, 2019 23:34 
Аватара пользователя

Зарегистрирован: Вторник, 04 Октябрь, 2011 17:45
Сообщения: 585
А вот мой любимый кусок кода из игры Tetris - шаг главного игрового алгоритма.
Данный шаг повторяется регулярно по таймеру.

Игра - это конечный автомат, а именно автомат Мура.
Автомат имеет следующие состояния:
- playing (играем)
- dropping (игрок запустил быстрое падение фигуры)
- finished (игра окончена).
Единственное входное значение - сигнал таймера (приходит в виде запуска функции advanceStep.
Вложение:
20190920140836.png
20190920140836.png [ 288.48 КБ | Просмотров: 12709 ]

Состояния чётко видны на ДРАКОН-схеме выше.
В зависимости от состояния, алгоритм производит различные действия и переходит в следующее состояние.

Функция advanceStep возвращает либо интервал, после которого следует вызвать её ещё раз, либо undefined,
что означает "выход из игрового цикла".

Вы уверены, что хотите увидеть равнозначный код в текстовом виде? Тогда вот вам:
Код:
function advanceStep() {
    switch (module.state) {
        case "playing":
            if (module.projectile) {
                if (canMoveDown()) {
                    moveDown()
                    return getStepPeriod()
                } else {
                    freezeProjectile()
                    if (clearRow()) {
                        return getStepPeriod()
                    } else {
                        createProjectile()
                        if (isGameLost()) {
                            gameOver()
                            module.state = "finished"
                            return undefined
                        } else {
                            return getStepPeriod()
                        }
                    }
                }
            } else {
                if (clearRow()) {
                    return getStepPeriod()
                } else {
                    createProjectile()
                    if (isGameLost()) {
                        gameOver()
                        module.state = "finished"
                        return undefined
                    } else {
                        return getStepPeriod()
                    }
                }
            }
        case "dropping":
            if (canMoveDown()) {
                moveDown()
                return DropPeriod
            } else {
                freezeProjectile()
                module.state = "playing"
                return getStepPeriod()
            }
        case "finished":
            return undefined
    }
}


Конечно, указанная выше ДРАКОН-схема тоже сложная и большая.
Её нельзя "понять" одним махом, как можно понять анекдот.
ДРАКОН помогает понять программу, но в ином смысле слова "понять":
Увидеть что должен сделать исполнитель в том или ином стечении обстоятельств.
В нашем случае ДРАКОН-схема показывает, что именно случится в игре во всех возможных ситуациях.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 03 Октябрь, 2019 11:50 

Зарегистрирован: Пятница, 08 Декабрь, 2017 18:24
Сообщения: 439
Откуда: Астрахань-Сочи
Супер! Буду использовать для примеров матёрым программистам, которые в Сириусе водятся в изрядном количестве.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 03 Октябрь, 2019 12:41 
Аватара пользователя

Зарегистрирован: Суббота, 29 Март, 2008 19:27
Сообщения: 1098
Откуда: Россия, Чебоксары
Степан Митькин писал(а):
Когда нет падающей фигуры (projectile), мы ничего не делаем
Настаиваю на том, что это и должен быть основной шампур.
Потому что выполняется постоянно, "сто тыщ мильонов раз", и является НОРМАЛЬНЫМ с точки зрения процесса.
А нажатие на кнопку - это СОБЫТИЕ, которое происходит редко. И оно нарушает нормальный ход процесса.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 03 Октябрь, 2019 14:17 
Аватара пользователя

Зарегистрирован: Вторник, 04 Октябрь, 2011 17:45
Сообщения: 585
Alexey_Donskoy писал(а):
Что касается предмета темы: скажу, что таблицы решений лучше деревьев.
Главное преимущество: полнота анализа вариантов, которую деревья не обеспечивают.

Мне таблицы решений тоже нравятся. Таблицы решений активно применяются в ERP.

Пример из жизни - выбор условий контракта на поставку.
Входные колонки: тоннаж, способ доставки, место доставки и валюта платежа.
Выходные колонки: номер склада, цена.
Эта таблица решений работает отлично.

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

Но есть и минусы:

Во-первых, адское количество повторов в таблицах.

Но самое страшное - не гибкие они. Некоторые вещи трудно передать через таблицы решений. А некоторые — невозможно.
В ДРАКОН-схеме можно задать вопрос, совершить действие, снова задать вопрос, снова совершить действие и т.п.
При этом мы:
- избегаем лишних повторов.
- можем совершать действия между вопросами. На примере advanceStep: после вопроса canMoveDown()? - ответ нет - выполняем freezeProjectile().
- можем избегать проверки некоторых условий, что важно, если проверки дорого стоят. На примере advanceStep: clearRow() - затратная процедура. Хорошо, что можно её иногда не вызывать.

Вывод:
Таблицы решений применяем в тех случаях, когда это оправдано (функциональная семантика - только чтение состояния во время проверки условий, малое количество проверок и вариантов условий, дешевизна проверок).
В подавляющем большинстве алгоритмов применяем ДРАКОН.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 03 Октябрь, 2019 23:32 
Аватара пользователя

Зарегистрирован: Суббота, 29 Март, 2008 19:27
Сообщения: 1098
Откуда: Россия, Чебоксары
Степан Митькин писал(а):
можем совершать действия между вопросами
Ну так это две и более РАЗНЫХ таблиц решения (в т.ч. вложенных).
Конечно, в одну таблицу такое впихнуть нельзя - да и незачем.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 04 Октябрь, 2019 09:11 

Зарегистрирован: Пятница, 08 Декабрь, 2017 18:24
Сообщения: 439
Откуда: Астрахань-Сочи
Собственно, вот и ответ: то что решается ОДНОЙ диаграммой на Драконе, можно решить НЕСКОЛЬКИМИ таблицами решений, еще и попутно применяя вложенность.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 04 Октябрь, 2019 15:30 
Аватара пользователя

Зарегистрирован: Суббота, 29 Март, 2008 19:27
Сообщения: 1098
Откуда: Россия, Чебоксары
Дмитрий Бардынин писал(а):
Собственно, вот и ответ: то что решается ОДНОЙ диаграммой на Драконе, можно решить НЕСКОЛЬКИМИ таблицами решений, еще и попутно применяя вложенность.
Ответ неверный.
Потому что диаграмма Дракона не гарантирует полноты анализа.
А это очень важное требование! Думаю, важнее, чем красота визуального отображения.

Конечно, можно решать эти вопросы интеллектуальным компилятором, самостоятельно проверяющим всё и вся, но это а) всё равно не гарантированно, б) применяется постфактум, для проверки - а лучше бы само проектирование изначально вести в нужной парадигме.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 04 Октябрь, 2019 15:33 

Зарегистрирован: Среда, 07 Январь, 2015 14:53
Сообщения: 1356
Alexey_Donskoy, в чём же заключается Ваша нужная, гарантирующая парадигма?

Процесс написания и рисования, всё таки является творческим, не однозначным!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 04 Октябрь, 2019 17:02 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 396
Степан Митькин писал(а):
Во-первых, адское количество повторов в таблицах.

Да, проблема лишь частично решается с помощью комплексных (многоуровневых) табличных заголовков (для столбцов/строк). Например ("функция трассы" -- определение системы переходов):
Robert L. Baber, David L. Parnas, Sergiy A. Vilkomir. Disciplined Methods of Software Specification: A Case Study.
Вложение:
trace_fn.png
trace_fn.png [ 57.54 КБ | Просмотров: 12596 ]


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 04 Октябрь, 2019 17:05 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 396
Есть ещё вот такая любопытная вариация таблиц в проекте CoCoVila:
Expert Tables in CoCoViLa
Вложение:
str_tbl1.png
str_tbl1.png [ 54.34 КБ | Просмотров: 12595 ]

Вложение:
str_tbl2.png
str_tbl2.png [ 134.2 КБ | Просмотров: 12595 ]


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 04 Октябрь, 2019 17:07 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 396
Степан Митькин писал(а):
можем совершать действия между вопросами

Да, в "классических" таблицах выражение отношения следования затруднительно. Хотя возможны "таблицы действий" в таком стиле -- из "Э. Хамби. Программирование таблиц решений":
Вложение:
hambi.png
hambi.png [ 280.38 КБ | Просмотров: 12595 ]

Или же даже "рекурсивные" таблицы (из документации к Filetab):
Вложение:
rec_tbl.png
rec_tbl.png [ 31.61 КБ | Просмотров: 12595 ]


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 04 Октябрь, 2019 17:09 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 396
А "гибкие" таблицы решений когда-то здесь на форуме обсуждались -- "схематические таблицы":
https://habr.com/ru/post/80893/

Причём в таблицах вида:

Изображение

с использованием принципа "операторных схем" -- указание узла-операции с входными/выходными связями для операндов -- дублирования ещё меньше, чем в ДРАКОН-схемах. Т.е., например, расчёт effectiveness (см. по ссылке выше) как:
Код:
effectiveness = power * (surprise ? 3 : 2)

отображается "как есть". В Дракон/блок-схемах же необходимо задавать два варианта операции в зависимости от условия, т.е. определять как:
Код:
if surprise then
  effectiveness = power * 3
else
  effectiveness = power * 2


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 04 Октябрь, 2019 18:59 

Зарегистрирован: Пятница, 08 Декабрь, 2017 18:24
Сообщения: 439
Откуда: Астрахань-Сочи
Цитата:
effectiveness = power * (surprise ? 3 : 2)
Это выражение и в Драконе написать можно, просто в Полке. Тернарный оператор - он и в Драконе тернарный :)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 08 Октябрь, 2019 18:30 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 396
Дмитрий Бардынин писал(а):
Цитата:
effectiveness = power * (surprise ? 3 : 2)
Это выражение и в Драконе написать можно, просто в Полке. Тернарный оператор - он и в Драконе тернарный :)

В таком случае нарушается нормализация представления алгоритма, также как, например, при вписывании "действий" в икону "вопрос" (стремясь к компактизации и т.п.).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 09 Октябрь, 2019 09:14 

Зарегистрирован: Пятница, 08 Декабрь, 2017 18:24
Сообщения: 439
Откуда: Астрахань-Сочи
Следуя вашей логике, нужно и оператор присваивания заменять везде. На "Полку"


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 09 Октябрь, 2019 16:26 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 396
Если, всё же, принять распространенный тезис о том, что дракон-схема -- это упорядоченная блок-схема, то тогда дракон-схемы относятся к классу чертежей граф-схема алгоритма. Линии (дуги) должны отражать отношение следования между "иконами" (вершинами), с возникающими альтернативами и циклами (а также "параллельность" и пр.). Семантика икон "полка", "действие", а также "ввод" и "вывод" отличается в разрезе семантической особенности предметного действия, команды и т.п. Как применяется оператор присваивания в качестве нагрузки в этих "иконах" -- прикладные особенности конкретной предметки (оператор присваивания не выражает отношение следования).

Кроме "внутренних условных операторов", критику или неоднозначность вызывает также и оператор ";" или его аналог как выражение последовательности, применяемый явно или неявно в "действиях" и др. иконах с целью компактизации из-за эргономичных соображений (чтобы избежать множество подряд расположенных икон-действий -- мол выражение одной мысли, о чём здесь на форуме недавно была дискуссия). Часто декларируется, что при трансформации алгоритма из текстовой формы в графическую как Д-схема ДРАКОН должен "изымать" все ключевые управляющие слова/конструкции. В итоге, в реальности, появляются исключения...
В чертежах вида граф-схема или штрих-схема подобная компактизация естественна -- действия располагаются рядом (плотно) последовательно, каждое помечается штрихом или кружочком-вершиной (к слову, по ссылке рассматриваются и потоки данных -- альтернатива "схематическим таблицам" выше):
https://forum.drakon.su/viewtopic.php?p=93258#p93228

В "ленивом ДРАКОН-е" не помешают, например, штрихи (как вершины на вертикальных линиях) для отметки действий (всё-таки по конструкции там нагрузка на вершины графа, а не на рёбра как в Р-схемах) -- также естественна компактизация действий:
https://forum.drakon.su/viewtopic.php?t=5616

В блок-схемах/ДРАКОН-е применяются образы геометрических фигур с замкнутым контуром, что имеет свои эргономичные плюшки в контексте прикладной нагрузки и восприятия (есть возможность вписать текст условно большого размера и т.д.). Однако, применение "управляющих" конструкций внутри прикладной нагрузки "икон" (а-ля "тернарные вопросы", "последовательности" и т.п.) придают ДРАКОН-формализму оттенок, свойственный таким языкам программирования как Ruby и ему подобным, где существуют десятки способов выражения одного и того же функционала (мол, зато наглядно, а скорее -- вычурно). Что, собственно то, в целом характерно для всей "программной инженерии" :). В прочей, материальной, инженерии в чертежах, как правило, максимально избегают многозначности.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 107 ]  На страницу 1, 2, 3, 4, 5, 6  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2008-2024, участники конференции «DRAKON.SU», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB