на главную страницу
визитка
темы

Семинары доктора Марцинкевича
(занятие шестнадцатое)

029.18 Взгляд со стороны пользователя или повторение - мать учения.

Ввод и вывод информации в массив

    Попробуем подойти к разработке программы со стороны пользователя. Пользователю нужно иметь возможность строить процесс и контролировать его течение.
   В настоящем случае перед нами будут стоять уже ранее решенные задачи в программе Memo3. И мы по сути займёмся с вами повторением пройденного материала в программе Pth2 т.о., что в процессе повторения будем отвечать на запросы пользователя. Другими словами, мы будем следовать за требованиями пользователя, который весь процесс "создает самостоятельно".
    Мысль, на которой мы остановились в программе Pth1, состояла в построении функции "физиологического рассогласования". Основная мысль там заключалась в аппроксимации нелинейных функций линейными. При этом мы помним, что мы занимаемся "реальными процессами", а не специально математикой, то есть исходим из того, "как это протекает в жизни", и в нашу задачу входит последовательное, шаг за шагом построение кривой произвольной функции. Это может выглядеть так, как чувствует себя путешественник, прокладывающий маршрут в зависимости от рельефа местности, открывающегося  из пункта, в котором он находится, до следующего пункта, в который ему нужно попасть. Другими словами, заранее кривая функции может быть неизвестна. Идея в духе: главное - не результат, главное - процесс.
    Очевидно, что способ приращений, примененный в программе Pth1, в этом случае не подходит, так как каждый последующий шаг в ней жестко определяется предыдущим, что "ограничивает свободу выбора". Должен быть заложен такой принцип, что каждый очередной сделанный шаг изменяет ситуацию подобно тому, как горизонт, который открывается нам с разных точек, различен. Поэтому функция в целом будет складываться из последовательности линейных отрезков. Напомню, что в качестве приращений аргумента нами рассматриваются переключения таймера, каждое из которых принимается за единицу. Так как на каждом отдельном шаге берется линейная функция, то если её записать в виде y=at, то, т.к. приращение t=1, то в зоне приращения y=a. Но при этом у нас шаг от шага "а" может изменяться и представлять собой функцию от времени. Вы помните, что при а=1 мы имеем тангенс угла, =45 градусам. Мы можем взять таблицу тангенсов, и, ориентируясь на неё, строить приращения функций, отражающей реальность. И можем в этом деле потренироваться, реализуя по шагам наперед заданную кривую или кривую, которая строится по мере развития нашей фантазии.
    Теперь о другом. Если каждый шаг путешествия рассматривать как решение частной задачи, связанной с созданием программы, задачи,  которая доставляет средства для решения в конечном счете задачи в целом, то для того, чтобы оказаться в конце пути, нам нужно пройти шаг за шагом весь путь.
    Мы начнём с того, что каждый шаг функции у нас будет храниться в массивах. При этом, конечно, желательно иметь возможность построения библиотеки важных для нас функций. В этом смысле мы должны иметь форму массива, которая может заполняться той или иной функцией, с одной стороны, и из которой функция могла бы выгружаться в текстовые файлы, с другой. Как вы помните, эта задача нами с вами была решена в программе Memo3. И сегодня мы должны просто показать, насколько хорошо нами усвоен материал.
   С чего начнём? Естественно, с загрузки в массив элементов и проверки того, что в ячейках массива находится именно то, что нам нужно.
   Но эта задача возвращает нас еще несколько назад, ведь мы должны знать, чего именно мы хотим именно на настоящем этапе разработки программы. А хотим мы линейно аппроксимировать заданную функцию, которая может быть нам задана наглядно в виде графика. Ведь сейчас мы занимаемся построением программы, а не её эксплуатацией. Поэтому нам нужно постоянно убеждаться, что программа на каждом отдельном шаге работает. От графического представления функции мы должны перейти к аналитическому выражению её приращений на каждом шаге и, соответственно, к её значениям для заданных значений последовательных дискрет (приращений) аргумента. Так мы и поступим: начнём с графика и от него перейдем к таблице приращений и значений функции. Когда мы получим таблицу, тогда нам будет ясно, что именно мы должны занести в массив и как можно вычислить значение функции для заданного аргумента. Итак, пусть дана функция рис.1 и нами построена таблица приращений аргумента:



t ∆Y Y
0 0 3
1 3 4,2
2 1,2 4,95
3 0,75 5,35
4 0,4 5,55
5 0,2 5,65
6 0,1 -2,65
7 -3 -1,45
8 -1,2 -0,7
9 -0,75 -0,3
10 -0,4 -0,2
11 -0,2 -0,1
12 -0,1 0
     

   

    Теперь, построив таблицу, мы можем заняться занесением её данных в массив и проверкой занесенных данных.


   Для этой цели нам потребуются средства для ввода и для контроля. Для выполнения отдельной операции мы будем использовать кнопку MMmass1 главного меню, которая открывается при нажатии на MMmas, окна (поля ввода-вывода) и метку (поле вывода) (Рис.2).
   В окно LEor будем вводить номер выполняемой операции, именно, мы введем в него 0, если хотим ввести информацию в ячейку, 1 - если хотим получить информацию о содержимом ячейки, 2 - если хотим последовательно, начиная с некоторой ячейки, записывать информацию в ячейки, 3 - если хотим последовательно, начиная с некоторой ячейки, просматривать содержимое ячеек.
   В окно LEi мы вводим номер ячейки (счет с ноля), в которую будем вводить информацию или выводить в режимах 0 (режим записи информации в ячейку) , 1 (режим вывода информации из ячейки в метку L1, а также будем вводить номер начальной ячейки массива, в которую хотим ввести информацию или вывести, а также в которой индицируется следующая заполняемая или открываемая ячейка, если это режимы 2, 3.
   В окно LEin записывается вводимая информация.
   В метку L1 выводится информация о содержимом ячейки.
   Пример:
   В исходном состоянии все элементы массива mass1[]={0}.
   Введем в LEor 0, в 5 (соответствует 6 ячейке массива, т.к. счет ячеек в массиве начинается с ноля), в LEi=0, в LEin - 1,5, нажмём кнопку MMmass1. В метке L1 высветится содержимое шестой ячейки.
   Пусть LEor=1, LEi=4, нажмем  MMmass1. Получим L1=0. Изменим значение LEi=5, клик на MMmass1, получаем L1=1,5.
   (LEor=2, LEi=0, LEin=1,5, MMmas1)=(LEi=1,L1=1,5)
   (LEor=2, LEi=1, LEin=2,5, L1=1,5, MMmass1)=((LEi=2,L1=2,5)
   (LEor=3, LEi=0, LEin=2,5, L1=2,5, MMmass1)=((LEi=1,L1=1,5)
   (LEor=3, LEi=1, LEin=1,5, L1=2,5, MMmass1)=((LEi=2,L1=2,5)

   Следующая задача состоит в загрузке информации из файла в массив и обратно. Эта задача выполняется при посредующей роли визуальных компонентов Memo файла "text.txt" и текстового файла. Файл "text.txt" вспомогательный. Он служит для хранения массива, с которым мы работаем "постоянно" в течение некоторого времени. Библиотека употребляемых массивов хранится в произвольном текстовом файле и организуется пользователем на его вкус. Когда нужно загрузить из библиотеки нужный массив, он копируется из неё и вставляется в Memo1, откуда загружается в общий (типовой) массив mass1
   Сделаем всё практически. Откроем у себя какой-нибудь текстовый редактор, например, блокнот, и запишем в нём данные массива, которые нами получены в таблице. Каждое следующее значение ячейки записывается с новой строки. Для удобства можем слева от значения ячеек записать номер ячеек. Но копировать мы будем, разумеется, только последовательность значений ячеек, начиная с нулевой. Поэтому если мы находимся в "блокноте", нам нужно будет иметь два экземпляра данных, как это показано на рис.3.


   Для записи данных в массив мы должны установить LEor=5 (режим записи данных из Memo1 в массив mass1) и установить в соответствующие значения интервал ячеек массива, в которые производится запись: в LEi - начальная, LEmass1for- конечная ячейка выбранного интервала массива. Однако следует иметь ввиду, что существует соответствие между строками Memo и номерами ячеек массива, поэтому в массив не могут записываться строки Memo, которые не содержат информации. Запись в массив сразу же проверяется путем извлечения данных из массива в третий столбец (Memo3). По данным первого столбца (Memo2) мы определяем границы записи. Например, если мы скопируем во второй столбец (Memo1) информацию, показанную на рис.4, и нажмём MMmass1, то в третьем столбце получим извлечение информации из соответствующих ячеек массива.
   Еще пример: Всё то же, что на рис. 4, но LEi=2, LEmass1for=9, MMmass1 , то получим контроль вывода записанного в третьем столбце, причем, начальная ячейка и конечная интервала определяются по значениям LEi иLEmass1for.
   Теперь выведем содержимое выбранного нами интервала ячеек массива в Memo1. Для этого сотрём информацию в Memo1 и установим LEor=6 (режим вывода информации из массива в Memo1). Запишем начало интервала в LEi, например,LEi=7, и конечную извлекаемую ячейку в LEmass1for, например, LEmass1for=20, нажимаем MMmass1 и получаем в Memo1 интервал значений ячеек массива.

   Если мы хотим в последующем продолжить работу с данными Memo1, нам достаточно нажать на MMdata и затем на MMsave. Когда мы в следующий раз откроем программу, то, нажав последовательно Mmdata, Mmload, мы восстановим предшествующее содержание Memo1.

Графики

    Графики мы рассматривали на предыдущем занятии, и это даёт нам основание полагать, что мы знаем, как с ними управляться. То новое, что появилось на сегодняшнем занятии - это формулирование универсального принципа построения всякой функции. В настоящем разделе мы лишь иллюстрируем построение графика на рассматриваемом нами случае. Мы уяснили себе, что если мы имеем дело с заданной функцией, то, если функция задана графически, то следует по графику определиться с приращениями функции на единицу приращения аргумента. Если функция задана аналитически, то снова мы должны вычислить приращения функции для последовательности единичных интервалов аргумента. Полученные результаты записываем построчно в произвольном редакторе, из которого затем копируем данные в Memo1, хотя, конечно, ничто не может нам помешать записать данные непосредственно в Memo1 . Затем записываем данные из Мемо1 в массив, после чего синхронизируем массив  с таймером, запускаем таймер и строим график функции.
   Итак, установите и включите программу Pth2 и постройте график, осуществив действия :
   Скопируйте функцию в Memo1, затем MMdata↓("знак нажать")→MMSave↓. Вы записали информацию в файл. Теперь представим, что мы только начали работать: TSdata↓→MMdata↓→ MMload↓→ LEor=5→LEi=0→LEmass1for=13→MMmass↓→MMmass1↓→TSprocess↓→LEinter=2000→LEsbros=100→LEpusk=1→MMprocess↓→MMpusk↓
   Начинается построение функции на заданном нами интервале значений дискрет аргумента, после чего таймер останавливается. Для того, чтобы повторить процесс с этой же или другой функцией, которую нужно раньше загрузить в массив, проделайте MMprocess↓→MMclear↓→LEpusk=1. Начнется новый цикл построения графика.

   07.03.09 г.