OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Пятница, 10 Июль, 2020 15:37

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




Начать новую тему Ответить на тему  [ Сообщений: 14 ] 
Автор Сообщение
СообщениеДобавлено: Пятница, 09 Март, 2012 20:38 
Аватара пользователя

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


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

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2934
Откуда: г. Ярославль
Давайте подумаем.

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

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 09 Март, 2012 21:18 
Аватара пользователя

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 09 Март, 2012 21:48 

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

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 09 Март, 2012 22:20 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2934
Откуда: г. Ярославль
Как-то так. В процедуре 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 
Аватара пользователя

Зарегистрирован: Суббота, 26 Ноябрь, 2011 16:26
Сообщения: 18
Откуда: Люберцы
Я так представляю себе структуру модуля:

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 10 Март, 2012 08:55 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2934
Откуда: г. Ярославль
Алгоритм заканчивается, когда лунолёт падает на поверхность :) Сделать проверку на отрицательную высоту, и всё. Если не ошибаюсь, в каком-то из алгоритмов "Лунолёта" так и было сделано.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 10 Март, 2012 09:39 
Аватара пользователя

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 10 Март, 2012 09:45 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9269
Откуда: Россия, Орёл
Лучше упаковать в запись...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 10 Март, 2012 09:53 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2934
Откуда: г. Ярославль
Так-то да, чем меньше глобальных переменных, тем лучше. У меня, например, таковых минимальное количество - только фабрики, интеракторы да какие-нибудь общесистемные элементы. Всё остальное разнесено по типам записей.

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 10 Март, 2012 11:55 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8337
Откуда: Троицк, Москва
Если вычисление перемежается (прерывается) вводом промежуточных данных, то нет никакого способа зафиксировать состояние процесса, кроме как используя глобальные переменные.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 10 Март, 2012 13:17 
Аватара пользователя

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 10 Март, 2012 15:06 
Аватара пользователя

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 11 Март, 2012 22:20 
Модератор
Аватара пользователя

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


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 

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


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

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


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

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