OberonCore
https://forum.oberoncore.ru/

Ввод даных в процессе выполнения программы
https://forum.oberoncore.ru/viewtopic.php?f=35&t=3883
Страница 1 из 1

Автор:  Александр Иноземцев [ Пятница, 09 Март, 2012 20:38 ]
Заголовок сообщения:  Ввод даных в процессе выполнения программы

Разбирал старые архивы программ и натолкнулся на текст программы на Borland Pascal "Лунолет-II". Вот ссылка на блок-схему. Под приступом ностальгии решил по-быстрому написать программу на ББ. Оказалось что простая программа, требующая ввода данных в ходе своей работы, на ББ будет для начинающего не совсем простой.
Вывод данных в журнал не составляет труда, а вот блок ввода промежуточных данных вызвал у меня некоторый "ступор". Неужели без создания диалогового окна никак нельзя обойтись? А как же "текст как интерфейс" ? :?
У меня в модуле имеется следующая строка IMPORT-а:
Код:
IMPORT Log := StdLog, In := i21sysIn, Math;
Есть ли способ при такой строке IMPORT-а реализовать промежуточный ввод данных?

Автор:  Иван Кузьмицкий [ Пятница, 09 Март, 2012 21:04 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

Давайте подумаем.

Я когда-то играл в "Лунолёт" ещё на калькуляторе МК-85. Помню, что коррекцию можно вводить на каждом шаге расчёта траектории. Коррекция задаётся двумя параметрами: угол тяги и масса расходуемого топлива. Потом запускаем расчёт и ждём результата - рассчитанных показаний текущей высоты и скорости.

Как подобный диалог можно реализовать с помощью идеологии текст-как-интерфейс?

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

Автор:  Александр Иноземцев [ Пятница, 09 Март, 2012 21:18 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

В данном случае вводится три параметра: угол, расход топлива, время маневра. Количество вводимых параметров - это второй вопрос.
Иван Кузьмицкий писал(а):
Я бы поступил следующим образом. В составном документе последовательно вводить коррекцию в виде двух чисел, разделённых пробелом или табуляцией. А результаты автоматически рассчитываются и выводятся в той же строчке, после табуляции. И тут же добавляется перевод строки, чтобы вводить коррекцию на следующем шаге.
Какие модули кроме трех, перечисленных в первом посте, надо еще подключить для реализации предложенного метода?

Автор:  Иван Кузьмицкий [ Пятница, 09 Март, 2012 21:48 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

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

P.S. Для начала, можно от автоматизации отказаться. Вводить три числа, выделять их и в меню запустить расчёт.

P.P.S. Заглянул в пример использования i21sysInObx. Можно ещё проще сделать, одним коммандером.

Автор:  Иван Кузьмицкий [ Пятница, 09 Март, 2012 22:20 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

Как-то так. В процедуре Next надо реализовать расчётную часть. А диалог с пользователем осуществляется посредством коммандеров и вывода в журнал.

Код:
MODULE TestMoonRider;

   IMPORT  In := i21sysIn,  Log := StdLog;

   (* расчёт следующего шага *)
   PROCEDURE Next* (a, f, t: REAL; OUT h, v: REAL);
   BEGIN
      (* тестовый расчёт *)
      h := (a + f)/t;
      v := (100* a);
   END Next;
   
   (* команда *)
   PROCEDURE Do*;
      VAR  angle, fuel, time, h, v: REAL;
   BEGIN
      In.Open; ASSERT(In.done);
      (* ввод *)
      In.Real(angle);   ASSERT(In.done); 
      In.Real(fuel);   ASSERT(In.done); 
      In.Real(time);   ASSERT(In.done);
      (* расчёт *)
      Next(angle, fuel, time, h, v);
      (* вывод результата *)
      Log.String('Текущая высота = '); Log.Real(h); Log.String(', текущая скорость = '); Log.Real(v); Log.Ln;
   END Do;

END TestMoonRider.

^Q TestMoonRider.Do 45 100 0.1
^Q TestMoonRider.Do 35 200 0.1
^Q TestMoonRider.Do 15 50 0.01
^Q TestMoonRider.Do 25 100 0.01
^Q TestMoonRider.Do 95 100 0.01


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

Автор:  Александр Иноземцев [ Пятница, 09 Март, 2012 23:16 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

Я так представляю себе структуру модуля:

1. Инициализация исходных данных (через коммандер).
2. Вывод текущей информации. Ввод промежуточных данных. Вычисления и анализ результатов. (через коммандер)

Вывод осуществляется в журнал. Ввод через коммандер с закрывающей частью (Ctrl+Shift+Q).
Вот только все расчетные переменные придется делать глобальными для модуля, что не есть хорошо. Кроме этого, нет явного окончания алгоритма (ну мне так кажется).

Автор:  Иван Кузьмицкий [ Суббота, 10 Март, 2012 08:55 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

Алгоритм заканчивается, когда лунолёт падает на поверхность :) Сделать проверку на отрицательную высоту, и всё. Если не ошибаюсь, в каком-то из алгоритмов "Лунолёта" так и было сделано.

Александр Иноземцев писал(а):
Вот только все расчетные переменные придется делать глобальными для модуля, что не есть хорошо.
Почему Вас это смущает? Этих переменных не настолько много, чтобы можно было запутаться. Ну а если всё же не хочется смешивать в одном месте промежуточные данные и диалоговые переменные, то расчёт вообще можно смело вынести в отдельный модуль.

Автор:  Александр Иноземцев [ Суббота, 10 Март, 2012 09:39 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

Об оформлении программ писал(а):
Должно быть как можно меньше глобальных переменных.
Значения глобальных переменных могут изменяться из любого места программы, в любое время. Это затрудняет отслеживание всех возможных взаимодействий (т.?наз. ?побочных эффектов?) с такими переменными. Тем самым увеличивается вероятность внесения ошибок при изменении их использования.
Я как бы об этом. Просто не красиво, на мой взгляд.
Вопрос такой: пока модуль загружен, в памяти хранится состояние только глобальных переменных модуля? И еще, как будет правильнее: 1) создать запись, которая описывает всю систему или 2) использовать глобальные переменные простых типов?

Автор:  Илья Ермаков [ Суббота, 10 Март, 2012 09:45 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

Лучше упаковать в запись...

Автор:  Иван Кузьмицкий [ Суббота, 10 Март, 2012 09:53 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

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

Конкретно для лунолёта я бы поступил так - всю алгоритмическую начинку оформил бы внутри типа RECORD.

Александр Иноземцев писал(а):
Вопрос такой: пока модуль загружен, в памяти хранится состояние только глобальных переменных модуля?
Да, именно так. Вы можете убедиться сами - выделите имя модуля и в меню Info выберите пункт Global Variables.

Автор:  Info21 [ Суббота, 10 Март, 2012 11:55 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

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

В этом не может быть ничего плохого или некрасивого: таково условие задачи.

Автор:  Александр Иноземцев [ Суббота, 10 Март, 2012 13:17 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

"Некрасиво" следует понимать в данной ситуации как не читабельно. Куча глобальных переменных как рассыпанные шарики. Отследить трудно. Воспринять еще труднее. Действительно, как заметил Илья Ермаков упаковать всю систему в запись - будет и понятнее и проще работать.
Я сейчас допишу код модуля и выложу тут. Так сказать, на суд общественности. Буду крайне признателен за комментарии и исправления.

Автор:  Info21 [ Суббота, 10 Март, 2012 15:06 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

Александр Иноземцев писал(а):
"Некрасиво" следует понимать в данной ситуации как не читабельно. Куча глобальных переменных как рассыпанные шарики. Отследить трудно. Воспринять еще труднее. Действительно, как заметил Илья Ермаков упаковать всю систему в запись - будет и понятнее и проще работать.
Где же они рассыпаны? В одном модуле, что ли?
А если вокруг них поставить RECORD .. END -- они будут менее рассыпаны? :)

M.v более рассыпано, чем M.r.v?

Автор:  Евгений Темиргалеев [ Воскресенье, 11 Март, 2012 22:20 ]
Заголовок сообщения:  Re: Ввод даных в процессе выполнения программы

Александр Иноземцев писал(а):
Действительно, как заметил Илья Ермаков упаковать всю систему в запись - будет и понятнее и проще работать.
Помещать в запись имеет смысл из опасения, когда глобальных переменных много и имена у них такие, что есть опасность пересечений с локальными. Но так бывает (на моём опыте) если изначально именовать глобальные "криво" (кратко). А так --- поглядите какой-нибудь Kernel, Dialog.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/