Штыров Валерий Яковлевич : другие произведения.

История создания одной машины

Самиздат: [Регистрация] [Найти] [Рейтинги] [Обсуждения] [Новинки] [Обзоры] [Помощь|Техвопросы]
Ссылки:
Школа кожевенного мастерства: сумки, ремни своими руками
 Ваша оценка:

L41 История создания одной машины

    Идея только постепенно обрастает мясом, причем, в разных местах и с разной скоростью.

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

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

Таблица 1
? против по
1 11 11
2 01 10
3 00 00
4 10 01
 []

     СУ - система управления, на которую, т.о., в зависимости от направления вращения вала будут подаваться различные последовательности пар сигналов. И по последовательностям этих наборов нужно определить направление вращение валаВращению против и по часовой стрелке  соответствуют пары импульсов столбцов таблицы 1.

    Задача, очевидно, поставлена самым общим образом, и мы позволим себе последовать за разработчиком, который от нечего делать взялся за её решение. Конечно, нас не могут интересовать те специфические приемы, которые он применяет, и, следовательно, нас не интересует программирование, притом, что разработчик реализует задачу, строя соответствующую программу. Нас не интересуют конкретные вещи, но - общий поток познания. То же обстоятельство, что он реализуется на специфическом материале, то от этого никуда не уйдешь, так что приходится принимать не только любовь как цель, но и женщину, которая является объектом любви.
    Знаком p.s. я обозначаю мои пояснительные вставки в поток мысли разработчика.


        1. Я откуда-то должен получить информацию. Допустим, это LE1, LE2. (p.s. LE с номером - это окно, в которое пользователь можем вводить информацию, а также получать информацию о состояниях машины) Причем, в первое записываю предыдущую информацию, во второе - последующую. Всю информацию я могу записать одновременно. Для меня важно лишь, чтобы она обрабатывалась в определенном порядке. Информация в LE1 может быть вначале какой угодно, то есть 11, 01, 00, 10, Но информация в LE2 является функцией от этих данных. То есть если 11, то следующей может быть только 01 либо 10, Если 01, то следующей может быть только 00, и, точно также, если 10, то следующая также будет 00. Если 00, то в одном случае это может быт 10, в другом - 01, и уже по этому можно судить о направлении вращения. Если 10, то следующая будет 11 для вращения против, 00 - для вращения вала по часовой стрелке.

      2.   Ещё раз: Если 11, то против часовой, если 01, и по, если 10. Если 01, то против часовой, если 00, и по, если 11. Если 10, то против часовой, если 11, и по, если 00. Если 00, то против часовой стрелки, если 10, и по, если 01.

   3. . Теперь всё это нужно реализовать в программном виде.

   4.. Какие варианты. Вопрос о вводе информации с 'прибора' о вращении. Можно было бы взять таймер , чтобы он на каждый очередной цикл выдавал очередные данные в зависимости от направления вращения
    (p.s. На практике мы, как правило, имеем дело с объектом, который действует независимо от нас и свойства и признаки и их соотношение мы должны отразить. В данном случае у нас нет объекта как физической данности, и мы должны создать его виртуальную имитацию, то есть не то, что нами чувственно воспринимается именно как объект, но проявления  действий объекта в виде информации. Так как в данном случае речь идет о вращении вала, то есть о движении, то естественно применить для этой цели таймер, который будет выдавать информацию о состоянии вала через определенные промежутки времени. Здесь уже неявно задается двойственность: с одной стороны, объект с его состояниями, с другой стороны - прибор, который воспринимает эти состояния, и система управления, которая по предшествующему и последующему состояниям определяет направление вращения вала.)

   5. Можно говорить о соответствии мысли и слова, поскольку преобразование мысли в слово характеризуется сложностью и неоднозначностью. Слово часто обозначает сложную мысль отдельным понятием, всю конкретику оставляя за бортом. Также вообще возникают затруднения с выражением мысли в словах не только потому, что не существует еще соответствующих понятий (слов) для выражения мысли, но существует также трудность в последовательном выражении мысли, поскольку мысль обычно является как актуальное целое, а не как последовательно становящееся.

   6. Если для этой цели применять принцип образца, в соответствии с которым осуществляется действие. Образец является постоянным в рамках действия, хотя он может изменяться с выходом из него. Для этой цели если применять массив с заданными в нём данными. Вернее, для различения направления вращения, два массива. Обращение к тому или другому массиву массиву зависит от заданного направления.

    (p.s. Всякая машина имеет пульт управления. При работе с программой мы имеем дело с таким пультом управления, через который управляем работой программы, то бишь машиной. Забегая вперед, я помещаю снимок рабочего  пульта  управления машиной.  

 []
    На нём показаны окна (метки), кнопки и таймер.)

void __fastcall TForm1::B1Click(TObject *Sender)

{
1 char S[]="строка";
2 char *Sp="предложение";
3 AnsiString Si[]={"пре","дло","же","ние"};
4 const AnsiString An[]={"11","01","00","10"};
5 const AnsiString nA[]={"11","10","00","01"};

6 LE1->Text=S[0];
7 LE2->Text=Sp[1];
8 LE5->Text=Si[0];
9 LE3->Text=An[0];
10 LE4->Text=nA[1];
}
//-------------------
Если char, то выводится только один символ, поэтому строка 3 с char вместо AnsiString не будет выполнена
    (p.s. 11, 01 и т.д. рассматриваются не как числа, а просто как набор символов, и разработчик, задавшись мыслью создания массива символов,  разочаровывается в том, что ячейки массивов типа char выдают  всего лишь один символ, тогда как ему нужно, чтобы в его образце хранилась их пара. Он всего лишь убеждается, что, задавая массивы символов двумя различными способами он затем может, указав адрес символа в массиве и вывести его значение в окно LE1. Лишь когда он перешел к строковым строчным переменным типа AnsiString, он реализовал свою цель - возможность в ячейках массива хранить произвольное число символов)

   7. Логику можно использовать не для реализации чего-то уже готового, а в процессе его построения. Это построение заключается в том, что оно так или иначе связано с последовательностью, а последовательность может быть определена посредством импликации именно потому, что если в ней нет антецедента (предшествующего члена), то не будет и консеквента (последующего члена), а это как раз и означает переходы от предыдущего к последующему, невозможность получить последующее, не получив предыдушее.

  8. Так, можно рассмотреть последовательность, которую я прошел: я начал co строковых массивов типа
char, затем перешел к массивам типа AnsiSnrbng, затем - к константным массивам. Реализация каждого из ходов ставит последующие задачи. С другой стороны, что, в общем, то же самое, можно говорить о пройденном пути. Мы получаем следующую схему: у нас возникает какая-то идея. Эта идея порождена реализацией идеи предшествующей, и совсем не обязательно результат реализации будет положительным. Различие лишь в том, что в случае положительного результата мы переходим к последующей части решаемой задачи, в случае отрицательного ищем иные средства решения подзадачи текущей. Т.о., можно считать, что мы имеем две стороны: реализацию одной идеи и возникновение другой, что можно записать в виде А/А→В/В→С/С и т.д. в случае положительного решения идеи, или, если  решение идеи отрицательно, то мы ищем иные средства для её решения до тех пор, пока идея не будет найдена или пока не будет доказано, что задача не имеет решения в существующих обстоятельствах: А/-А1 →А/А2...  В числителе у нас будет идея, в знаменателе её реализация. Поэтому, если реализация не получается, то отрицается идея, то есть если А/-А→В,  то есть идея  А преобразуется в какую-то другую идею В. Если объединить понятие идеи и её  положительной реализации в одном знаке, то получим просто проходимый пусть А →В, В →С и т.д. или сокращенно А →В →С →... Во всяком случае, если этот путь к чему-то приводит, то тем самым задается последовательность (программа) действий. По сути речь идет о действиях относительно реальностей, порождаемых действиями.

  9. Задача, которая решалась и которая решена - создание образца последовательности, которой характеризуется вращение вала в одном либо другом направлении. Начало движения было положено идеей массивов. Но char-массив не позволял вывести 01. Это позволил сделать (константный) AnsiSnring массив. Константный, потому что массив не должен изменяться. Следующая задача - снятие текущих данных с работающей машины и сравнение их с образцами, которые хранятся в массивах, обработка полученных результатов и выдача направления вращения вала. На первом этапе можно вводить информацию с LE, следующая идея заключается в использовании таймера.

    (p.s. Конечно, идея таймера относится к построению объекта управления, тогда как то, чем сейчас занимается разработчик, это система управления)

  10.  Как обычно, основным принципом является последовательное разворачивание того, что впоследствии окажется целостным механизмом. Очередной шаг - ввод в LE1 информации и занесение её значения в переменную AnsiString val. Далее - сравнение значения val со значениями ячеек в  массиве. Что должно быть следствием сравнения? Результатом сравнения должно быть введение букв а,b,c,d, представляющих собой сокращение состояний машины. Для этой цели используем switch.
    (p.s. В данном случае, как и в предшествующем, мы имеем дело с кашей у разработчика: с несколькими идеями в попытке состыковать их друг с другом. Переменная по имени val может содержать в себе только одно значение. Разработчик хочет обозначить наборы значений 11,01,00,10 одной буквой, и для реализации этой цели пытается использовать оператор множественного выбора switch.)

 Сравнение: что-то, что может иметь много значений, что-то, что имеет одно значение. Что-то, что может иметь много значений, разделяется в switch по строкам, в каждой из которых имеет место одно значение, и оно сравнивается с тем, что имеет одно значение.

  
void __fastcall TForm1::B3Click(TObject *Sender)
{
AnsiString Znach;
int val;
val=StrToInt(LE1->Text);

switch ( val)
{
case 3 : Znach="a";
break;
case 2 : Znach="b";
break;
case 1 : Znach="c";
break;
case 0 : Znach="d";
};
LE2->Text=Znach;
}
//-----------------------
   (
p.s. Разработчик в данном случае хитрит: он задает переменной val тип целых, интерпретируя 00 как 0, 01 как 1, 10 как 2, 11 как 3 То, что он делает в этой программе, это обозначает наборы 11, 10,01, 00 буквами а,b,c,d. У него что-то, насколько можно понять, не понятое, связанное с применением switch и он пытается избавиться от двух строковых символов, заменив их одним. фактически он занимается просто перенаименованием  11 в "а" и т.д.)
   
    Это рабочий switch. В метках case записаны постоянные, val также имеет определенное значение. Но мне нужны строковые переменные.

   
void __fastcall TForm1::B1Click(TObject *Sender)
{
switch ('01')
{
case '00' : Znach="a";
break;
case '01' : Znach="b";
break;
case '10': Znach="c";
break;
case '11' : Znach="d";
};
LE2->Text=Znach;
}
//------------------------
Тоже рабочая. То есть константа '01' находится в существующем наборе.
Следующая рабочая программа:
  
void __fastcall TForm1::B1Click(TObject *Sender)
{
const AnsiString An[]={"11","01","00","10"};
AnsiString val, Znach;
val = LE1->Text;
if(val == An[1])Znach="à";
else Znach = "b";
LE3->Text=An[1];
LE4->Text=Znach;
LE2->Text=An[0];
}
//------------------------------------
Здесь следующие замечания: строковые вводятся в LE без кавычек, так как текст и предполагается.

   
(p.s. это опыты разработчика, связанные с рассмотрением им того, как работают функции. Речь для него, следовательно, идет о возможностях применения орудий. Другими словами, его опыты связаны с его собственной ограниченностью. У него возникает ощущение тупика и он отказывается от применения switch. Тем не менее, всё это движение представляет собой пример движения вперед маленькими шажками, каждый из который приводит к какому-то положительному результату. Ведь когда результат отрицательный, то последующий шаг определяется неопределенным вектором. Тогда как положительный результат ограничивает неопределенность, открывая путь к какой-то следующему, пусть маленькому, но положительному шагу.)

    Дальше сделаю с for, чтобы найти нужный вариант из множества.

void __fastcall TForm1::B3Click(TObject *Sender)
{

const AnsiString An[]={"11","01","00","10"};
//const AnsiString nA[]={"11","10","00","01"};

AnsiString val=0;

val = LE1->Text;
for(int i=0; i<4; i++){
if(val == An[i]) {
LE2->Text=An[i];
LE5->Text=IntToStr(i); }
}

}
//---------------------------------------------------


    (p.s.Задавая в LE1 значения, которые может принимать информация с вращающегося вала, получаем номер и соответствующее содержание ячейки массива в окнах LE5 и LE2 соответственно)

    Но у нас не один массив, а два, и каждый из них представляет одно из двух  противоположных направлений вращения вала. Одно и то же входное значение мы можем проверить на обоих массивах и при этом можем получить как одинаковые, так и различные значения. Если мы получим одинаковые значения, то следующими будут разные, и если мы получим разные значения, то следующими будут одинаковые. Одинаковые - это 11 либо 00, разные - это 01 либо 10. Отсюда получаем: если 11, то если 01, то направление вращения а, или против часовой стрелки. Если 11, то если 10, то в, т.е. по часовой стрелке. Если 00, то если 10, то против, если 01, то по. 11 →.01 →а; 11 →.10 →в; 00 →.10 →а; 00 →01 →в. 11 ˫ 01 → a, 10 →b. 00 ˫ 10 → a, 01 →b. Теперь нам нужно создать тавтологию. Мысль: правило перехода от логических выражений к программированию их на машине. Например, берем ячейку var1, в которую будем записывать 11 либо 00, var2, в которую будем записывать 01 либо 10. Заметим, что 01=1, 00=0, 10=2, 11=3.

    (p.s. Идея здесь заключается в представлении того, что в действительности происходит во времени, то есть последовательно, выражается пространственно, то есть что сосуществует параллельно. Цель - временные вещи представить как существующие пространственно. Тогда задача опосредованного выражения временных отношений через  пространственные будет заключаться в последовательности выполнения актуально существующих элементов пространства. Для этой цели используется импликация. Например, два выражения А→.В→С и В→.А→С с логической точки зрения эквивалентны, однако с содержательной они означают различную последовательность выполнения одновременно, то есть пространственно и актуально  существующих элементов. В первом выражении  посылку В невозможно применить раньше посылки А, так как только предварительное применение посылки А дает доказательство истинности импликации В→С, что является необходимым условием для вывода об истинности С при условии истинности В. Соответственно, аналогом импликации при программировании является оператор if, который и применяется для выражения импликативных выражений)

    Одному обороту соответствуют 4 парных сигнала.
    Вопрос о двух массивах и их равенства или нет. Для равенства двух массивов нужно сравнивать равенство соответствующих ячеек. Если содержимое соответствующих ячеек одинаково, то можно говорить о равенстве массивов.
    Вращение вала генерирует, в зависимости от его направления, различные двоичные последовательности символов.
    Отсюда получаем:
    Если 11, то если 01, то а и если 10, то b
    Если 00, то если 10, то а и если 01, то b
    если 10, то если 11, то а, и если 00, то b
    если 01, то если 11, то b, и если 00, то а
 11 →01 ↓10 ("↓" -  "либо")
 00→01↓10
 01→11↓00
 10→11↓00

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

   Мы имеем дело с последовательностью сигналов. Примем, что предшествующий сигнал записывается в LE1, последующий сигнал - в LE2., после чего последующий становится предшествующим, следовательно, переписывается в LE1, а в LE2 записывается следующий за ним сигнал. Позже это можно будет заменить двумя функциями, выдающими последовательности сигналов, соответствующих одному либо другому направлению вращения вала. В LE3 будет записываться индекс направления вращения вала, определяемый на основании двух состояний системы. Введем переменные, соответствующие LE1 = le1, LE2= le2, LE3= le3. Соответственно, мы получаем множество возможных наборов значений:
11,01 →а, 1
11,10 →в 2
00,10 →а 3
00,01 →в 4
01,00 →а 5
01,11 →в 6
10,11 →а 7
10,00 →в 8
   Отсюда получаем множество условных предложений: если 11, то если 01, то а и т.д.

   Программа:
    1. Запись информации из LE1, LE2 в le1, le2 соответственно.
    2. Переходим к проверке полученной информации на основе форм, например,  если le1 & le2 = истине, то le3=а. Т.о., нами определяется направление вращения вала по двум непосредственно следующим друг за другом состояниям. Если же имеет место ложь, то переход к рассмотрению следующего состояния. Мы при этом можем применять операцию if. Чтобы применить операцию switch, мы всё это дело должны усложнить, придав, с одной стороны, индексы каждому из наборов 1, 2, ...,8, и также определив набор текущих состояний.
    3. Окна LE1к, LE2к LE3k - для контроля выполняемых операций

   Затем, здесь важна такая вещь, как последовательность, поскольку 11,01 и 01, 11 не только не равны друг другу, но означают противоположные направления. Значит, последующее возможно только при условии существования предыдущего. Мы не можем (p.s. с логической точки зрения, см. замечание выше) при этом применить формулу А →.В →С, так как она равна А&В →С. Тем не менее, определенная последовательность во всем этом всё-таки есть. Пусть выводимо (знак читается "следует") А →.В →С. По закону дедукции имеем: А, В С. Но в действительности из А →.В →С выводимо С тогда и только тогда, если (А →.В →С) →.А →.В →С. Тогда по теореме дедукции А →.В →С, А, В С. Мы не можем к А →.В →С применить В раньше, чем применим А. Другое дело, что А →.В →С ≡ В →.С →С. Но это не меняет сути дела: последовательность применения посылок в выводе определяется общей формулой
 []

void __fastcall TForm1::B1Click(TObject *Sender)

{
AnsiString le1, le2, le3;
le1=LE1->Text;
le2=LE2->Text;
LE1k->Text = le1;
LE2k->Text =le2;
if (le1 == "11"){
if (le2 == "01")le3="a";
if(le2 == "10")le3="b";
LE3->Text =le3;
}
}

   (p.s. Программа предназначана для проверки идеи, определяющей направление вращения вала по двум его состояниям, предшествующему и последующему. Для этого вводятся в ячейки le1, le2 из окон LE1, LE2 следующие друг за другом наборы значений сигналов в зависимости от направления вращения вала, и по ним определяется направление вращения вала а либо b. Логическая схема - если А(первая пара сигналов), то если В (вторая пара сигналов), то а (одно направление вращения вала), если С (вторая из возможных пар сигналов), то b (противоположное а направление вращения вала) )

   12. Теперь остаётся задать все возможные варианты последовательностей. Получаем:

    void __fastcall TForm1::B1Click(TObject *Sender)
    {
   
    AnsiString le1, le2, le3;
    le1=LE1->Text;
    le2=LE2->Text;
    LE1k->Text = le1;
    LE2k->Text =le2;
    if (le1 == "11"){
    if (le2 == "01")le3="a";
   
    if(le2 == "10")le3="b";
    LE3->Text =le3;
    }
   
    if (le1 == "00"){
    if (le2 == "01")le3="b";
   
    if(le2 == "10")le3="a";
    LE3->Text =le3;
    }
   
    if (le1 == "01"){
    if (le2 == "11")le3="b";
   
    if(le2 == "00")le3="a";
    LE3->Text =le3;
    }
   
    if (le1 == "10"){
    if (le2 == "11")le3="a";
   
    if(le2 == "00")le3="b";
    LE3->Text =le3;
    }
    }
    //---------------------------------------------------------------------------

   (p.s. Т.о., первая часть задачи - создание прибора, снимающего сигналы с вращающегося вала, и определяющего  по ним его направление, решена)

   13. Теперь нам нужно сделать  генератор. Машина в целом вырисовывается т.о.: мы включаем вращение вала и его направление, которое контролируется индексами 'а', 'b'. Для этого нужен таймер.  По окончании каждого такта работы таймер должен выполнять набор операций. Какие это  операции?

   13 Таймер. Запустить и остановить. Операции таймера после прохождения интервала времени. Допустим, мы запустили таймер. Здесь идея какая - научиться записывать последовательность действий. Итак, есть множество действий. Наша задача - расположить их в определенном порядке т.о.,  чтобы было что-то реализовано. Это разные вещи - последовательность действий и действия сами по себе. Нужно иметь действия которые понадобятся, и нужно расположить их в определенном порядке.

    14 После того, как таймер запущен и отработал, он должен выполнить последовательность операций, он должен; 1. переписать информацию из LE2 в LE1 и записать информацию в LE2. Откуда он будет брать эту информацию? Может быть, из соответствующих массивов, причем, в один такт он должен брать информацию из одной ячейки массива и запоминать, из какой ячейки он будет брать информацию на следующем такте. Эта величина будет равна i? принимающей значения 0-3. Кажется, что для этого можно применить операцию for. Но тогда весь процесс должен протекать внутри этой операции. Можем использовать оператор if, то есть попробовать собрать весь механизм вручную. Как тогда всё это должно выглядеть? Во первых, у нас есть i с начальным значением ноль. Значения i должны проверяться, и если i равно трём, то на следующем шаге оно должно обнуляться. Вводим int i=0; AnsiString le1, le2; const AnsiString An[]={"11","01","00","10"}; Нам нужно на каждом такте таймера извлекать значения из массива Аn[i]. По окончании такта i++ (должно увеличиваться на единицу) и проверяться : если i =4, то i=0. Эту часть мы сделали т.о.:

    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
    const AnsiString An[]={"11","01","00","10"};
 
    AnsiString le1=0, le2=0, LE3=0;
    LE2->Text=le2;
    LE1->Text= LE2->Text;
    le1=LE1->Text;
    LE1k->Text = le1;
    i++;
    if (i==4)i=0;
    LE4->Text = IntToStr(i);
    }
   (p.s. Эта программка - просто опыт записи содержимого le2 в le1 и обнуления i, когда оно становится равно 4.. То есть относится к области не что нечто сделать, а как)

   
    Теперь нужно заняться извлечением значений из массива в le2. Получили:
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
    const AnsiString An[]={"11","01","00","10"};
    int i=0;
    AnsiString le1=0, le2=0, LE3=0;
    LE2->Text=le2;
    LE1->Text= LE2->Text;
    le1=LE1->Text;
    LE1k->Text = le1; //перемещение информации из2 в le1
    switch (i){
    case 0 : le2=An[0];
    break;
    case 1 : le2=An[1];
    break;
    case 2 : le2=An[2];
    break;
    case 3 : le2=An[3];
   
    }
    LE5->Text=le2; // Извлечение информации из массива по тактам таймера
   
    i++;
    if (i==4)i=0; //контроль i
    }
(p.s. Кольцевая последовательность извлечения элементов массива по тактам таймера осуществляется в данном случае вручную, нажатием кнопки В1. Т.о., если извлечение элементов массива будет привязано к тактам таймера, то будет решена задача создания имитатора вращения вала, правда, пока что только в одном направлении. Мы видим, что switch, опыты с которым разработчик делал в самом начале, теперь ему пригодился. Мы видим также, что на каждом шаге разработчик решает какую-то маленькую задачу, чем обеспечивается ему знание не только того, что, может быть, следует сделать, но и как это можно сделать. Что сделать и как - это совершенно разные вещи. Когда сегодня говорят о новой индустриализации, о национальном вопросе и пр. и пр., все это относится к тому, что нужно сделать, но это не отвечает на основной вопрос: как это сделать. Как это сделать - изначально никто не знает, и ответ на этот вопрос может дать только опыт, только опытный поиск ответов. Задача состоит совершенно не в том, чтобы инстинктивно-рефлекторно реагировать на опыты реальности, а в том, чтобы изучать эти опыты со стороны их объективного содержания, существующих в них причинно-следственных связей и т.п.)

   15. Какие следующие шаги. Направление вращения лучше всего задавать введением соответствующей информации в LE6. 0 - против, 1 - по часовой стрелке. Соответственно, эту функцию выполнит ячейка le6. В зависимости от ноля либо единицы идет загрузка из массива Аn либо nA. Следовательно, должны быть: запись из LE6 в le6, опрос le6 и если 0, то An, если 1, то nA, то есть должно осуществляться обращение к разным switch. Т.о., получаем:
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
    const AnsiString An[]={"11","01","00","10"};
    const AnsiString nA[]={"11","10","00","01"};
    AnsiString le1=0, le2=0, LE3=0, le6;
    LE2->Text=le2;
    LE1->Text= LE2->Text;
    le1=LE1->Text;
    LE1k->Text = le1; //перемещение из le2 d le1
    le6=LE6->Text; //направление вращения
    if(le6==0){
    switch (i){
    case 0 : le2=An[0];
    break;
    case 1 : le2=An[1];
    break;
    case 2 : le2=An[2];
    break;
    case 3 : le2=An[3];
    }
    }
    //вращение против часовой стрелки (a)
    if(le6==1){
    switch (i){
    case 0 : le2=nA[0];
    break;
    case 1 : le2=nA[1];
    break;
    case 2 : le2=nA[2];
    break;
    case 3 : le2=nA[3];
    break;
    }
    } // вращение по часовой стрелке
    LE5->Text=le2;
    i++;
    if (i==4)i=0;
    LE4->Text = IntToStr(i); //контроль i
    }
    (p.s. Операции, которые выполняются таймером по окончании каждого цикла. Но для этого таймер должен быть запущен с определенной скоростью. Это делается в подпрограмме кнопки В2.)

    Скорость, мониторинг, направление состояний есть. То есть мы можем задать вращение вала с определенной скоростью и в определенном направлении. Однако мы не можем этого сделать изначально, но только запустив машину в определенных направлениях и скорости:

    //---------------------------------------------------------------------------
    void __fastcall TForm1::B2Click(TObject *Sender)
    {
    LE6->Text=le6; //начальное направление
    LE5->Text=IntToStr(le5); //мониторинг скорости
    Timer1 -> Interval=le5;
    Timer1 -> Enabled = true;//первоначальная скорость таймера
    }
    //---------------------------------------------------------------------------
   
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
    const AnsiString An[]={"11","01","00","10"};
    const AnsiString nA[]={"11","10","00","01"}; //массивы направлений вращения
    le5=StrToInt(LE5->Text);
    Timer1 -> Interval=le5; //изменение скорости таймера
    le1=le2;
    LE1->Text = le1;
    LE2->Text = le2; //перемещение из e2 в le1 и мониторинг
    le6=StrToInt(LE6->Text); //вращение по и против часовой стрелки
    if(le6==0){
    switch (i){
    case 0 : le2=An[0];
    break;
    case 1 : le2=An[1];
    break;
    case 2 : le2=An[2];
    break;
    case 3 : le2=An[3];
    }
    }
    if(le6==1){
    switch (i){
    case 0 : le2=nA[0];
    break;
    case 1 : le2=nA[1];
    break;
    case 2 : le2=nA[2];
    break;
    case 3 : le2=nA[3];
    }
    }
    LE1->Text=le1;
    LE2->Text=le2;//мониторинг состояний
    i++;
    if (i==4)i=0;
    LE4->Text = IntToStr(i); //контроль i
    }
    //------------------------
    (p.s.Итак, виртуальный механизм, имитирующий вращение вала, создан. Однако:)

    Вначале нужно в окнах задать направление вращения и скорость вращения и затем через окна же их регулировать. Если окна остались пустыми, нужно попросить их заполнить. Однако оказалось, что если программа запущена, то при каждом очередном нажатии на пусковую кнопку все начальные установки снова воспроизводятся, тогда как они должны появляться только один раз. 
    В программе одним из ключевых моментов является, что выполняется раньше, что - позже.
    Кстати, следует поговорить о Виртуальных объектах, например, виртуальные кубики и их свойства. И о действиях  с виртуальными объектами. Речь идет о философии виртуальных объектов. Именно, виртуализировать в реальных объектах мы можем их признаки и свойства. Признаки объекта - это то, на основании чего, с одной стороны, можно говорить о том, что их совокупность позволяет "узнать" объект. С другой стороны,  существует соответствие между признаками и свойствами, то есть тем, что как может действовать объект, и здесь же присутствует и противоположная сторона - как можно действовать на объект с тем, чтобы получить у него определенные свойства. Итак, если объект обладает определенными признаками, то им соответствуют свойства объекта, то есть способы его действия. В этом смысле признак как форма проявления объекта актуализируется в своих свойствах, то есть в способности действовать. Но важна не только способность действовать, но и способность воспринимать действия, что также представляет свойства объекта, но уже не активные, а пассивные, и эти свойства объекта также отражаются в его признаках. Например, шахматные фигуры: каждая из шахматных фигур имеет присущую ей форму, что соответствует её признаку, с которым соотносится её свойство - ходить определенным образом.

    Решаем проблему сл.о.
    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    LE5->Text="скорость";
    LE6->Text="направление";
    }

    Итак, мы теперь можем задать направление и включить машину.  И нам нужно суметь снять данные  машины. Для этой цели достаточно подключить к машине виртуальный прибор, который был создан  раньше. И в результате нами получена программа в целом:  (p.s. файл h создается автоматически)

//---------------------------------------------------------------------------

#include
#pragma hdrstop

#include "UImp.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "PERFGRAP"
#pragma resource "*.dfm"
TForm1 *Form1;
int le5=0,i=0, le6=2;//скорость вращения, ? ячейки массива, направление вращения 0,1
AnsiString le1=0, le2=0, le3=0; // две переменные состояния
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
LE5->Text="скорость";
LE6->Text="направление";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::B2Click(TObject *Sender)
{



le5=StrToInt(LE5->Text);
le6=StrToInt(LE5->Text); //занесение скорости и направления в окна
Timer1 -> Interval=le5;
Timer1 -> Enabled = true;//первоначальная скорость таймера
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
const AnsiString An[]={"11","01","00","10"};
const AnsiString nA[]={"11","10","00","01"}; //массивы направлений вращения

le5=StrToInt(LE5->Text);
Timer1 -> Interval=le5; //изменение скорости таймера



le1=le2;
LE1->Text = le1;
LE2->Text = le2; //перемещение из le2 в le1

le6=StrToInt(LE6->Text); //вращение против и по часовой стрелкe

if(le6==0){

switch (i){
case 0 : le2=An[0];
break;
case 1 : le2=An[1];
break;
case 2 : le2=An[2];
break;
case 3 : le2=An[3];
}

}
if(le6==1){
switch (i){
case 0 : le2=nA[0];
break;
case 1 : le2=nA[1];
break;
case 2 : le2=nA[2];
break;
case 3 : le2=nA[3];

}

}
LE1->Text=le1;
LE2->Text=le2;//мониторинг состояний


i++;
if (i==4)i=0;
LE4->Text = IntToStr(i); //контроль i

//=======================================
le1=LE1->Text;
le2=LE2->Text;

if (le1 == "11"){
if (le2 == "01")le3="a";

if(le2 == "10")le3="b";
LE3->Text =le3;
}

if (le1 == "00"){
if (le2 == "01")le3="b";

if(le2 == "10")le3="a";
LE3->Text =le3;
}

if (le1 == "01"){
if (le2 == "11")le3="b";

if(le2 == "00")le3="a";
LE3->Text =le3;
}

if (le1 == "10"){
if (le2 == "11")le3="a";

if(le2 == "00")le3="b";
LE3->Text =le3;
}





}
//---------------------------------------------------------------------------

void __fastcall TForm1::stopClick(TObject *Sender)
{
Timer1 -> Interval=0;
Timer1 -> Enabled = false;
}
//---------------------------------------------------------------------------

    На этом записи разработчика заканчиваются. После того, как были убраны на пульте управления вспомогательные элементы, пульт приобрел вид:
 []    Теперь можно скачать бинарный файл  PImp , открыть  и убедиться, что виртуальная машина работает. Для этого задайте в окне (метке) LЕ5 скорость. Минимальный цикл таймера - 1 мс, однако точность его работы из-за накладных расходов обеспечивается  где-то с секунды, то есть с 1000 и выше. В окне LE6 - направление  вращения 0- против, 1 - по часовой стрелке. В окнах LELE2 показываются предшествующее и последующее состояния машины, в окне   LE3 выдается направление вращения вала, так что можно соотнести то направление, которое вы задали, и то, которое показывает машина. Соответствие между заданием и данными машины 0 - а, 1- b. Окно LE4 указывает на такты цикла машины.
    Логика работы машины: Кнопкой В2 запускается таймер. В самом таймере размещена вся программа, которая выполняется по импульсам отработки таймера. Кнопкой stop  таймер выключается и "вал перестает вращаться". Перестройка работы таймера может производиться во время его работы путем введения новых данных в окна LE5,  LE6. Таймер может останавливаться  и снова запускаться с того места, на котором остановился..
    Все это - техническая сторона дела, которая нас не очень интересует, но без которой обойтись невозможно. То, что нас интересует, это познавательные процессы, которыми обеспечивается построение машины.
    При этом сразу же будем иметь ввиду, что мы имеем дело с определенным человеком и с его собственными способами решать задачу. Другой человек может применять  иные стратегии, соответствующие его природным данным. Однако, во всяком случае, все стратегии, какими бы они ни были, характеризуются общими принципами, которые "светятся" в них.
    Задается задача в общем виде. Следующий шаг связан с построением логики решения задачи, то есть того, что именно нужно сделать, чтобы задача была решена. При этом у одних эта логика может быть явно задана, у других, как в настоящем случае, она имеется ввиду, то есть явно не формулируется и явно не составляется определенного плана. По сути, в этом последнем случае преследуется только общее направление движения к цели, конкретные же шаги при построении программы определяются успехом или неуспехом предыдущих шагов. Успех или неуспех каждого шага определяется нахождением или не нахождением ответа на вопрос, как сделать то, что следует сделать. Если ответа не находится, то начинаются поиски иных средств или же, в случае неуспеха и в последнем случае, составляется новый план того, что нужно сделать, то есть новая траектория движения к цели. 
    Вначале пути мы наблюдаем как бы разминку разработчика, который только еще входит в свой предмет. У него возникает идея использования строчных массивов, извлечение их которых он пытается сделать при помощи switch, но у него из этого ничего не получается. Однако, во всяком случае, в этих попытках он узнал кое-что о том, как работает switch. Когда со switch он зашел в тупик, он перешел к if, и на почве if практически сразу- нет, не возникла идея, а просто самими обстоятельствами, рефлекторным чувством была создана идея прибора, снимающего данные с машины. Эти обстоятельства реализовались в том, что движение происходило мелкими шажками, на каждом из которых решалась своя маленькая, частичная задача, тем не менее, всегда связанная с определенной идеей. Первой была идея использования строковых массивов. Вторая идея - представления временных отношений, предшествующего и последующего в актуальном пространстве, когда оба состояния есть налицо (в LE1, LE2), временной же характер достигается последовательностью переработки данных, для чего использовалась формула вида А→.В→С, которая позволила в логике выражать временные процессы. Теорема дедукции в логике этот процесс показывает наглядно, именно определяя последовательность, характеризующая вывод. Например,   (А→.В→С)→.А→.В→С В соответствии с теоремой дедукции дает: А→.В→С, А, В Ⱶ С. Доказательство С заключается в определенной последовательности вывода: А→.В→С, АⱵВ→С, В Ⱶ С.  Не выполнив первый вывод, невозможно выполнить второй. Проекция логики на чувственную реальность  дает определенную последовательность  реализации событий А, В, С. Если бы  мы захотели высказываться языком Гегеля, то должны были бы сказать, что у нас есть выражение АD, где в D светится А→В, то есть в реальности реализация события А порождает отношение между событиями В→С. Гегель исходит из принципа времени, тогда как формальная логика время превращает в пространство, в котором, вообще говоря, вопрос перехода от одних его точек к другим является довольно  произвольным. Так, с точки зрения логики, А→.В→С=В→.А→С=А&В→С. Тем не менее, несмотря на известную свободу направлений движений в пространстве, они могут быть ограничены определенными направлениями в силу существования направленных связей, своего рода "силовых линий" пространства, выражаемых в логике импликацией. Так, мы не можем от  С перейти ни к А, ни к В. Разработчику нужно было обеспечить непрерывную последовательность смены состояний. Так как каждый последующий цикл характеризуется тем, что настоящее его состояние превращается в предыдущее, и это нужно было осознать разработчику, то перед ним стал вопрос о том, как это сделать. Ответ - перемещением информации из ячейки lе2, представляющей "настоящее" состояние машины, в ячейку  lе1, которой представляется её предшествующее во времени состояние.
    Следующая особенность по сути своей инстинктивного движения разработчика является то, что всё его движение разбивается как бы на две части. Одна часть связана с решением частичных задач. Этот этап можно назвать аналитическим. Когда в основном средства решения задачи собраны, наступает следующий этап - этап синтеза. Мы видели, как стремительно были построены два блока программы - прибора и объекта, состояния которого отражает прибор, а также соединение этих блоков  в машину. Кажется, что только что еще ничего не было, и "вдруг", "скачком", появилось всё. Однако это "вдруг" подготовлено аналитической фазой решения задачи, причем, оказалось, что использовались не только положительные, но и отрицательные результаты опыта, имеется ввиду применение switch при построении объекта,  имитирующего  вращения вала.
    Последний тупик, перед которым оказался разработчик, заключается в том, что при каждом нажатии на кнопку пуск машина начинала отрабатывать, начиная с  начальных состояний, а не продолжать отрабатывать существующие. И здесь также понадобилась идея - о последовательности работы программы. Лишь после того, как разработчик упрятал начальные состояния в Form, их воспроизводство при повторных нажатия на кнопку В2 прекратилось, что говорит о том, что программа через форму проходит только один раз.



    02.02.2012 г.


 Ваша оценка:

Связаться с программистом сайта.

Новые книги авторов СИ, вышедшие из печати:
О.Болдырева "Крадуш. Чужие души" М.Николаев "Вторжение на Землю"

Как попасть в этoт список

Кожевенное мастерство | Сайт "Художники" | Доска об'явлений "Книги"