02.02. МАЛЕВИЧ, ГОВОРИТЕ?

Перейти вниз

02.02. МАЛЕВИЧ, ГОВОРИТЕ?

Сообщение автор Gudleifr в Сб Дек 09, 2017 10:26 am

ГЛАВА ВТОРАЯ. МАЛЕВИЧ, ГОВОРИТЕ?

Конечно, разнообразные языки разработкти создавались и раньше:

СЕПУЛЕНИЕ СЕПУЛЕК

Общие места из документа "Система структурного документирования CWEB (Версия 3.0), 1994, Дональд Э.Кнут и Сильвио Леви. Перевод на русский язык: Сергей Короп - PS, 0.3Мб.
***

ВВЕДЕНИЕ. Суть философии CWEB в том, что программисты, желающие снабдить свою программу наилучшей документацией, должны одновременно пользоваться языком, подобным TeX, для подготовки документации и языком, подобным C, для программирования. Ни тот, ни другой сам по себе не предоставляет всего необходимого, но будучи должным образом объединены, оказываются куда более полезными, чем порознь.

Структура компьютерной программы может быть представлена, как "сеть" ("web" - "паутина"), состоящая из множества взаимно зависимых частей. Чтобы документировать такую программу, необходимо описать каждую такую часть и ее взаимоотношения с другими. Средства обработки текстов, предоставляемые TeX, позволяют нам описать локальную структуру каждой части программы, а средства программирования языка С - формально и однозначно специфицировать алгоритмы. Объединив их, мы получаем стиль программирования, максимально способствующий пониманию структуры сложных программ, и одновременно - хорошо документированные программы, для которых автоматически обеспечивается взаимное соответствие программы и документации.

Система CWEB состоит из двух программ, названных CWEAVE и CTANGLE. При программировании в системе CWEB программа на языке C и документация к ней объединены в одном файле, называемом CWEB-файл, с именем вроде something.w. Команда 'cweave something' создает файл something.tex, который с помощью TeX превращается в красиво оформленную ("pretty printed") версию something.w, которая соблюдает все типографские соглашения, такие как дизайн страницы, использование отступов, курсивных и жирных шрифтов, математических символов. Дополнительно автоматически строится система перекрестных ссылок. Аналогично, команда 'ctangle something' порождает программу на языке C something.c, которая может быть откомпилирована в исполнимый код.

Помимо предоставления удобного средства документирования, CWEB расширяет язык C возможностью менять местами части текста программы, так что большие программные системы могут быть восприняты целиком в терминах небольших секций и их локальных взаимосвязей. Программа CTANGLE названа так потому, что она расставляет секции web-структуры в порядке, требуемом C; преимуществом программирования в CWEB является то, что алгоритмы могут быть выражены в "развернутой" форме, в которой каждая секция объясняется отдельно от других. Программа CWEAVE, в соответствии своему названию, "сплетает" содержащиеся в каждой секции TeX- и C-части в структурированный документ. Возможно, не случайно немецким эквивалентом "weave" является "wele", а соответствующий им латинский императив - "texe"!

Пользователь CWEB должен быть хороню знаком с языком С. Минимальное знакомство с TeX также желательно, но фактически может быть получено уже в процессе работы с CWEB, поскольку простой текст подготавливается в TeX практически без какого-либо знания его языка. Тем, кто хорошо знаком с обеими системами потребуются совсем небольшие усилия, чтобы изучить команды CWEB.

ОБЗОР. Содержимым файлов CWEB может быть TeX-текст и С-текст. CWEB-программист должен четко представлять все происходящее с ними как в процессе генерации документации, так и программы, т.е. знать суть всех тех действий, которые будут производиться над CWEB-файлом программами CWEAVE и CTANGLE. Текст в формате TeX полностью копируется программой CWEAVE и игнорируется CTANGLE, это "чистая документация". С другой стороны, C-программа форматируется CWEAVE и преобразуется CTANGLE...

CWEB-файл содержит секции, которые более или менее самодостаточны. Каждая секция состоит из трех частей:

TeX-часть, содержащая материал, разъясняющий суть содержимого секции.
Промежуточная (middle) часть содержит макроопределения, служащие сокращениями для C-конструкций, которые неудобно выписывать каждый раз заново. Они преобразуются CTANGLE в макросы препроцессора.
C-часть, содержащая часть программы, генерируемой CTANGLE. Длина C-части в идеале не должна превышать дюжины строчек, чтобы она составляла законченный фрагмент программы и была легко понимаемой.

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

CWEB-файл может содержать произвольный текст, располагающийся перед началом первой секции и не входящий ни в одну из секций. Подобный текст далее будем именовать "преамбулой" ("in limbo"), он игнорируется CTANGLE и полностью копируется CWEAVE, так что его назначение состоит в определении произвольных инструкций TeX'a. Как правило, эти инструкции загружают требуемые шрифты, определяют макросы, изменяют размеры страницы и/или генерируют титульный лист.

Секции нумеруются последовательно, начиная с 1. Эти номера появляются в начале каждой секции в TeX-документе, полученном CWEAVE, а также в комментариях, отмечающих начало и конец каждой секции в С-программе, сгенерированной CTANGLE.

ИМЕНА СЕКЦИЙ. К счастью, нет никакой надобности нумеровать секции вручную... их номера будут сгенерированы CWEAVE и CTANGLE автоматически. При необходимости секции может быть присвоено имя вместо номера... Для наглядности имя секции должно быть хорошим описанием содержимого секции, т.е. пояснять абстракцию, представленную секцией. Впоследствии секция может быть "встроена" в другие секции так, что малозначимые детали ее реализации окажутся скрытыми. Имя секции, следовательно, должно быть достаточно длинным, чтобы выразить при этом ее суть.

К сожалению, утомительно и чревато ошибками писать длинное имя секции снова и снова. Поэтому CTANGLE и CWEAVE позволяют использовать сокращения...

ЧТО ДЕЛАЕТ CTANGLE? Конструкция ... имя ... может появиться в теле С-секции произвольное количество раз: последующие ссылки на имя означают его "использование", а не "объявление", т.е. что именованная секция, определенная где-либо еще, должна быть вставлена в это место C-программы. Действительно, основная идея CTANGLE - создать программу, объединив некоторое количество именованных и неименованных секций. Точные правила такого объединения таковы: вначале все макроопределения... преобразуются в инструкции препроцессора и собираются в начале файла. Далее туда копируются неименованные C-секции. Так образуется первое приближение текста программы (должна существовать хотя бы одна неименованная секция). Затем все имена секций, найденные в полученном тексте, заменяются C-частями соответствующих секций и этот процесс подстановки продолжается до разрешения всех ссылок. Все комментарии удаляются, поскольку полученная программа на С не предназначается для чтения человеком. Если одно и то же имя было дано более чем одной секции, С-фрагмент получается объединением C-частей всех таких секций. Это оказывается полезным, например, если имеется секция с именем 'Global variables', в которой будут собраны все глобальные переменные, где бы они ни были объявлены. Когда несколько секций имеют одинаковое имя, CWEAVE полагает номер первой из них номером, соответствующим этому имени, и она вставляет в конец секции ссылку: 'See also sections ...' ("См. также секции ..."), в которой перечислены номера всех остальных секций, имеющих это же имя.

Когда CTANGLE начинает и оканчивает обработку секции, она вставляет в выходной файл директивы препроцессора #line, так что номера строк в сообщениях об ошибках и при отладке программы будут ссылаться на исходный CWEB-файл. Благодаря этому, в большинстве случаев о получаемом С-файле можно просто забыть.

ЧТО ДЕЛАЕТ CWEAVE? Общая идея CWEAVE - создать из файла CWEB файл .tex таким образом: первая строка получаемого файла .tex указывает TeX'y загрузить файл макроопределений, описывающих формат CWEB-документов. Далее в tex-файл копируется текст преамбулы, расположенный перед первой секцией. Затем следует по очереди вывод каждой секции, возможно вперемешку с командами окончания страницы. Наконец, CWEAVE генерирует систему перекрестных ссылок: для каждого C-идентификатора указываются номера всех секций, в которых он используется, а также строится алфавитный список всех имен секций, а также оглавление, содержащее номера страниц и секций для всех "заглавных" секций.

Вы спросите, что такое "заглавная" секция...? Секции, которые ... обозначают начало новой группы секций. Такие группы в документе TeX всегда начинают новую страницу, и их имя используется в колонтитуле всех последующих страниц до появления очередной заглавной секции. Имя группы также заносится в оглавление и печатается в начале секции жирным шрифтом.

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

...

***

Почему я обозвал эту прелесть "сепульками"?

"Сепульки - играющий значительную роль элемент цивилизации ардритов (см.) с планеты Интеропия (см.). См. Сепулькарии".- Я последовая этому совету и прочитал:
"Сепулькарии - устройства, служащие для сепуления (см.)".- Поискал сепуление, там было:
"Сепуление - занятие ардритов (см.) с планеты Интеропия. (см.) См. Сепульки".

Именно так и выглядит (и работает - тоже) текстовая (пусть и красиво отформатированная-оформленная) документация на программу, изготовленная подобным способом. Это называется "Литературным программированием" (изначально, это ошибка перевода: "literate" - грамотное).
Если интересно, посмотрите написанное похожим образом описание самой системы TeX - 500 страниц математически-строгой программистской красотищи. Пожалуй, единственная целиком структурно написанная сложная программа, исходники которой я видел.
Однако, я совершенно не уверен, что такое может написать "обычный программист". Или, даже, прочесть-разобраться. Дело в том, что все 500 страниц написаны на честном Pascal (конечно, хорошо откомментированном), не вводится никакого проблемно-ориентированного лексикона, который бы позволил нам описывать суть программы краткими словами. Постоянно же перепрыгивать с уровня абстракций на "елочки if-ов" и обратно (с заходом на поиск "сепулек")... для этого надо быть воистину "структурным программистом".
Почему "дерево перекрестных ссылок" удалено из процесса разработки и появляется только как часть выходной документации? Что произойдет с TeX-частями в процессе отладки программы? Насколько правка TeX-макросов будет способна порушить код программы? Нет, прав был Брукс: "Я пользуюсь практическим правилом, согласно которому программный продукт (а именно его создание и подразумевает "литературное программирование") стоит, по меньшей мере, втрое дороже, чем просто отлаженная программа с такой же функциональностью".
Воспринимать этот метод, как способ облегчить жизнь программиста, нельзя.
***

Если вы хотите попробовать понять, насколько управляем CWEB-код, посмотрите код приключенческой игры - TXT, 0.2Мб. Конечно, для чтения предназначен только распечатанный TeX-документ, но писать-то предлагается в CWEB...
avatar
Gudleifr
Admin

Сообщения : 879
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.02. МАЛЕВИЧ, ГОВОРИТЕ?

Сообщение автор Gudleifr в Сб Дек 09, 2017 10:36 am

Т.к. мой инструментарий не располагает к подобным красивостям, вернемся в древние времена:

О.В.ЖУКОВ / ГЕНЕРАЦИЯ ПРОГРАММ ОБРАБОТКИ ДАННЫХ / 1976
Основополагающие огрызки:
***

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

В книге описаны пакеты простой и сложной структуры. Большое внимание уделено пакетам программ, обеспечивающим формирование и использование базы данных, и пакету генерации программных комплексов (ГПК). Это объясняется тем, что на использовании базы данных основана работа всех пакетов, а пакет ГПК обеспечивает выполнение всех функций пакетов программ (простой структуры) преобразований информационных массивов, редактирования и печати выходных ведомостей.

Программный комплекс (ПРК) - система программ (сегментов), выполнение которых в определенной последовательности необходимо для реализации требуемого алгоритма обработки данных; один из этих сегментов является головным...

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

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

Генератор-интерпретатор при формировании рабочей программы модифицирует свое тело в соответствии c входными параметрами, и сформированная программа сразу же исполняется (без записи в библиотеку). Поэтому рабочая программа перед выполнением каждый раз формируется в оперативной памяти. Генератор-компилятор по заданным параметрам формирует рабочую программу, которая записывается в библиотеку программ и может многократно использоваться при обработке данных. Генераторы-интерпретаторы могут составить основу оперативно настраиваемых комплексов решения типовых задач АСУ (например, информационно-справочных задач). Эта гибкость обеспечивается тем, что каждый раз при выполнении некоторой процедуры осуществляется генерация рабочей программы. Этот недостаток отсутствует при использовании генераторов-компиляторов, но имеет место другой - рабочая программа жестко настроена в соответствии с заданными параметрами. При построении ГПК принято компромиссное решение: в формируемых рабочих программах существуют средства модификации этих программ с тем, чтобы была возможность использовать программный комплекс при решении задачи для различных однородных объектов. Модификация программ осуществляется путем автоматической замены имен массивов, магнитных лент (МЛ), нестандартных блоков пользователя, подключаемых к программам обработки данных.

Блоки формирования базы данных обеспечивают ввод описаний данных в систему, оформление их виде специальных массивов - "каталогов описаний". Эти описания используются для настройки стандартных процедур обработки информационных массивов.

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

Управляющая программа программного комплекса (УППК) организует поочередное выполнение программ обработки данных; она определяет имя очередной обрабатывающей программы, загружает ее и передает на нее управление. Обрабатывающие программы могут представлять собой стандартные программы обработки данных, внешние программы к некоторым стандартным программам, специально разработанные нестандартные программы обработки конкретных данных. Такое разделение функций в программном комплексе позволяет унифицировать его составные части, а в дальнейшем автоматически формировать их.

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

ПРК может иметь различную степень обобщенности (приспособленности) к обработке информации для различных объектов. При смене объектов может появиться необходимость в программах ПРК менять имена массивов, МЛ, программ обработки, этапов обработки, нестандартных блоков пользователя (БЛПО), подключаемых к стандартным программам, а также структуру ПРК, т.е. состав и взаимосвязи входящих в него программ обработки информационных массивов. Рассмотрим возможные степени (уровни) обобщенности ПРК.

ПЕРВАЯ СТЕПЕНЬ ОБОБЩЕННОСТИ. Такой ПРК служит для решения типовой задачи только для одного объекта. Подобные ПРК могут быть применены для решения задач на другом объекте, если имена и структуры используемых информационных массивов на обоих объектах одинаковы. Каталоги описаний данных при работе ПРК не используются.

ВТОРАЯ СТЕПЕНЬ ОБОБЩЕННОСТИ. ПРК решения типовой задачи для группы однородных объектов. При использовании такого ПРК для конкретного объекта настройка осуществляется путем указания Оператором с ПМ (пишущей машинки) обозначения данного объекта, которое используется для модификации имен массивов, МЛ и БЛПО. Имеются два варианта реализации.

А. При работе программ обработки массивов осуществляется модификация имен массивов и магнитных лент в рабочих описаниях массивов (РОМ), программ обработки и имен БЛПО. В этом случае структуры записей, длины зон массивов, соответствующих всем объектам, должны быть строго идентичны; каталоги при работе ПРК не используются.

Б. При работе программ обработки массивов осуществляется модификация имен массивов в РОМ программ обработки и имен БЛПО, а из каталога с использованием модифицированных имен массивов считываются постоянные описания массивов (ПОМ) соответствующих массивов. В этом случае требования к идентичности структур массивов, относящихся к различным объектам, снижаются: длина записей и зон может быть различна, но величины (реквизиты) записей, использованные в обработке, должны иметь одинаковое внутреннее представление и положение внутри записей.

ТРЕТЬЯ СТЕПЕНЬ ОБОБЩЕННОСТИ. ПРК решения типовой задачи для группы объектов, для которых соответствующие массивы могут иметь различную структуру, но имена величин, использованных в обработке, должны быть во всех массивах одинаковыми. В этом случае может производиться модификация имен массивов, МЛ и БЛПО, требуется использование каталогов описаний, а программы обработки работают как генераторы-интерпретаторы, которые включаются в работу внешними программами, загружаемыми управляющей программой ПРК. Внешние программы для генераторов-интерпретаторов или для обобщенных программ, реализующих типовые алгоритмы обработки данных, формируются с обеспечением выполнения всех требований, предъявляемых к программам ПРК решения задач для группы однородных объектов (см. выше). ПРК третьей степени обобщенности могут быть построены из программ пакетов простой структуры.

Таким образом, программный комплекс, имеющий средства адаптации, позволяющие использовать этот ПРК для решения типовой задачи на многих объектах, является пакетом программ сложной структуры. А поэтому средство, которое служит для автоматического формирования таких ПРК, является генератором пакетов программ решения типовых задач АСУ.

УППК выполняет следующие основные функции:

- управляет последовательностью выполнения этапов обработки;
- принимает с ПМ имя очередного этапа обработки;
- автоматически определяет имя очередного этапа обработки, проверяя заданные условия;
- организует загрузку программы ОБМЕН требуемой модификации;
- принимает с ПМ имя объекта, для которого необходимо проводить обработку;
- запускает программу очередного этапа решения задачи (загрузка программы, передача на нее управления);
- информирует оператора о ходе выполнения этапов обработки, в том числе о некоторых аварийных ситуациях;
- резервирует на МЛ содержимое области ООБ при прекращении выполнения ПРК.

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

Выполнение ПРК разбито на отдельные этапы. Содержанием этапа могут быть ввод, вывод, контроль, сортировка, слияние, выборка, арифметические преобразования и т.п. информационных массивов. Кроме того, как указывалось выше, отдельным этапом может быть выполнение сложного вычислительного процесса, управляемого собственной управляющей программой. Такой этап МЫ будем называть составным. После выполнения этапа может быть необходима проверка с целью определения очередного этапа. Если необходимо определить, который этап (ЭТАП2 или ЭТАП3) выполнять после завершения этапа ЭТАП1, осуществляется проверка в блоке проверки условия УСЛ1. Блок УСЛ1 входит в состав этапа ЭТАП1.

Если же необходимо определить очередной этап из трех возможных: ЭТАП2, ЭТАП4, ЭТАП5, то проверка осуществляется в два приема: в блоке УСЛ2 и в блоке УСЛ3. Блок УСЛ2 входит в состав этапа ЭТАП1, а блок УСЛ3 - в состав этапа ЭТАП3.

В начале выполнения каждой УППК на пишущую машинку (ПМ) выводится некоторый "начальный текст", являющийся кратким содержанием вычислительного процесса или его названием. В конце выполнения ПРК на ПМ выводится "конечный текст", который информирует Оператора о прекращении выполнения вычислительного процесса.

Каждая программа обработки информационных массивов состоит из настраивающей части и динамической части. Основная функция первой части - подготовить все необходимые таблицы и константы, загрузить необходимые программы, модифицировать названия массивов, МЛ, БЛПО, ввести в ОЗУ из каталога описания массивов, распределить динамическую область для полей обмена с МЛ, открыть массивы для записи и для чтения, считать в ОЗУ первые зоны входных массивов. Динамическая часть программы содержит блоки, выполняющие следующие функции: определение действительных адресов всех величин, участвующих в процессе обработки, выполнение собственно процесса обработки, определение адресов очередных записей в полях обмена, анализ состояния обработки с целью определения конца работы, завершение работы (закрытие массивов, перемотка МЛ и т.п.).

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

Обмен информацией между УППК и программами обработки осуществляется через общую область.

Программы обработки информационных массивов:

- Сортировка массива
- Сортировка массива с уплотнением
- Сортировка массива с суммированием и уплотнением
- Слияние массивов
- Слияние массивов с суммированием и уплотнением
- Слияние упорядоченных массивов с исключением
- Разделение массива записей на несколько массивов по заданным условиям
- Обьединение записей двух одинакого упорядоченных массивов
- Контроль значений ключевых признаков записей массива по словарю значений
- Корректировка информационных массивов
- Пересечение двух массивов с умножением числа записей
- Корректировка значений отдельных величин записей
- Корректировка значений величин на заданную дельту
- Формирование массивов из входных массивов
- Преобразование записей массива, удовлетворяющих условию
- Вычисление нарастающего итога
- Вычисление ступенчатого итога
- Уплотнение упорядоченного массива с подсчетом одинаковых записей и формированием выходной записи по формату, определенному в описании записи
- Уплотнение массива с суммированием заданных величин (без перемены формата)
- Присоединение массивов
- Уплотнение массива с преобразованием данных из "уплотненных" записей по условию
- Редактирование результирующего массива для вывода выходных ведомостей на АЦПУ

...

***

Далее в книге подробно расписаны язык УППК, форматы всех необходимых таблиц, перфокарт и бланков. Практически все, кроме машинного кода системы.
Но, интересно, наверное, другое:

- Неочевидность позиции программиста по отношению к программному комплексу. Это совершенно неприемлемо для большинства современных программистов, "точно знающих" свое место в разработке сложнейшего аппаратно-программного комплекса, который занимает, по словам босса, 90% рынка компьютерных услуг. А тут - и системотехник, и быдлокодер, и пользователь - в одном лице, и, возможно, даже в течение одного рабочего дня.
- Второе - роль Оператора в комплексе. Не в смысле: Оператор нужен, т.к. мало денег дали интерфейс-дизайнеру; а в смысле: так проще и удобнее, в т.ч. и пользователю.
- Третье - мы видим, что, чем законченнее и совершеннее система, тем естественнее оставление в ней "дыр" для добавления пользовательского кода.
- Наконец, четвертое - что благополучно "побежденная" языками программирования высокого уровня проблема "структуризации, объектирования и прочиего абстрагирования данных" опять вылезает, как только мы начинаем делать что-то реальное. Все эти "степени обобщенности" нам придется прочувствовать.

И стоит ли так сильно отходить от привычного: "Написал ровно то, что прописано в Техническом Задании"?
Зачем? Скажу за себя.
Готов потратить на написание этих записок год-два и получить простое средство быстро и удобно сделать то, что мне надо, но не готов обновлять каждый год до конца жизни свое железо и программы. Не готов, вместо написания чего-то своего, изучать, опять же перманентно, один монструознее другого модные-патентованные способы сделать это по-чайниковски (или профессионально, что в наше время одно и то же).
***

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



Т.о. появляется, пусть и против желания программиста, некоторый язык, объединяющий действия оператора/пользователя и управляющие конструкции языка программирования.
И именно его и следует формализовать и упростиь до такой степени, чтобы можно было легко реализовать простейшими средствами...


Последний раз редактировалось: Gudleifr (Вт Фев 20, 2018 1:47 pm), всего редактировалось 1 раз(а)
avatar
Gudleifr
Admin

Сообщения : 879
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.02. МАЛЕВИЧ, ГОВОРИТЕ?

Сообщение автор Gudleifr в Сб Дек 09, 2017 11:12 am

ЗАДАЧА 1 ("ПРАВИЛА"). ЭТАП 1 ("СКРИПТЫ")

Когда я начал осваивать IBM PC, мне очень понравился NORTON COMMANDER - одна из первых, и, наименее требовательная к умственным способностям пользователя, программа визуального управления DOS-файлами. Быстро найти на диске игру, быстро ее запустить, быстро перенести на другой компьютер, даже, немножко подправить файлы конфигурации... Что еще надо?
Однако, чем больше я программировал персоналки, те больше меня NORTON раздражал. Слишком он был плохо заточен, чтобы быть полезным инструментом.
Тогда я вспомнил о виденной ранее очень удачной системе Pascal-программирования - UCSD:


Когда система загружена впервые, ею выдается строка-подсказка вида
Команды: E(dit, R(un, F(ile, C(omp, L(ink, X(ecute, A(ssem, D(ebug.
По команде Е пользователь переводится на один уровень ниже и попадает в Редактор (Editor), где выдается новая строка-подсказка. Она может иметь вид
Редактор: A(djst, C(py, D(lete, F(ind, I(nsrt, J(mp, R(eplace, Q(uit, X(chng, Z(ap.
По команде I система запрашивает у пользователя вводимый текст. По команде Q пользователь выходит из Редактора и возвращается к корню дерева (начальной строке-подсказке).

Нажимаешь клавишу - вызываешь нужный редактор/компилятор. Выбранная программа отработала, возвращаешься к исходному выбору.
И все это элементарно реализовалось на убогом языке скриптов MS DOS.
Вот, например, "рабочее место", в котором я несколько лет правил DOS-версию своего FOBOS:

@ ECHO OFF
SGR
C:
CD \CRAZY\FORTH
:LOOP
ECHO ***** FOBOS ***** Softfeet 1992-2000 *****
ECHO A)ssembler E)xit D)ebug G)ame L)ist M)ake N)ote P)roject R)un T)ime
ASK AaEeDdLlMmNnRrTtGgPp
IF ERRORLEVEL 19 GOTO PROJECT
IF ERRORLEVEL 17 GOTO GAME
IF ERRORLEVEL 15 GOTO TIME
IF ERRORLEVEL 13 GOTO RUN
IF ERRORLEVEL 11 GOTO NOTE
IF ERRORLEVEL 9 GOTO MAKE
IF ERRORLEVEL 7 GOTO LIST
IF ERRORLEVEL 5 GOTO DEBUG
IF ERRORLEVEL 3 QUIT
NE G1.ASM
GOTO LOOP
:PROJECT
NE FORTH.ALG
GOTO LOOP
:GAME
NE \GAMES\TXT\NEXT.ALG
GOTO LOOP
:DEBUG
DEBUG G1.COM
GOTO LOOP
:LIST
NE G1.LST
GOTO LOOP
:MAKE
MAKE G1
GOTO LOOP
:NOTE
NE \TXT\NOTE.TXT
GOTO LOOP
:RUN
G1
GOTO LOOP
:TIME
TIME <\BAT\YES.DAT
GOTO LOOP

Недостающие программы - SGR (установка цвета) и ASK (запрос литеры) - были написаны в DEBUG за минуты. Невзирая на простоту, в этом скрипте можно найти основные черты программ-интерпретаторов (в т.ч. FORTH).
Конечно, в наш визуальный век надо вместо "создайте цикл, включающий нужные команды" писать "создайте окно-папочку, в которой разместите иконки-ссылки"... Но, честно говоря, "цикл" проще и удобннее. По двум причинам: можно оптимизирувать процесс работы и можно прописать все эти локализации и настройки путей, которые жутко мешают Windows-автоматизации.

Еще одна проблема состоит в организации обмена данными между командами.
К сожалению, даже расширенное (юниксовское) понимание файла, не просто как именованной области диска, а как канала связи/синхронизации процессов, нам мало чем поможет (ну, там, направить выход одной команды на вход другой, следующей за ней в ОС-скрипте...).

Есть три решения, использующее дисковые файлы:
1. "Регистровая модель" (см. выше первую степень обобщенности). Для каждого данного придумать особое имя файла, которое и будут использовать все заинтересованные команды. Минус - невозможность команды использовать данные из других файлов. Зато, можно каждому имени приписать определенный смысл, т.е., в философском смысле, считать обращение к данным отдельным видом процедуры.
2. "Переменные". Использование косвенных ссылок на имена файлов. Можно, конечно. Но не слишком ли сложно? Если команды могут конфликтовать из-за одного имени файла, то кто им запретит конфликтовать из-за одинаковых имен переменых?
3. "Стек". Как ни странно, организовать стек файлов не просто, а очень просто. Берем исходное имя базы и добавляем к его имени номер или другой довесок. В система не сильно ограничивающих имена файлов вполне удобно иметь стек: файл.txt, файл.txt.txt, файл.txt.txt.txt и т.д. Т.о. "вырезатель" вполне естественно берет с вершины стека один файл и разбиваеет его на два.

К сожалению, GW-BASIC имеет наикривейшую реализацию доступа к файловой системе, поэтому проще всего перебирать файлы стека или списка "снаружи" - в командном файле, передавая BASIC-у текушее имя в переменной окружения. Например, так:

@ ECHO OFF
REM В ЭТОМ ФАЙЛЕ БУДЕМ НАКАПЛИВАТЬ РЕЗУЛЬТАТЫ
IF EXIST DX.ALG DEL DX.ALG
SET NUM1=0
SET NUM2=0
:LOOP
REM ПЕРЕРЕМЕННАЯ С ТЕКУЩИМ ИМЕНЕМ
SET FOP=D%NUM1%%NUM2%.ALG
IF NOT EXIST %FOP% GOTO DONE
REM ЗАПУСКАЕМ, НАПРИМЕР, ВЫРЕЗАТЕЛЬ  
GWBASIC PROG.BAS
REM СОХРАНЯЕМ ОСТАТОК ПОСЛЕ ВЫРЕЗАНИЯ
REN DY.ALG %FOP%
IF %NUM2%==9 GOTO ADD1
SET /A NUM2=%NUM2%+1
GOTO LOOP
:ADD1
SET NUM2=0
SET /A NUM1=%NUM1%+1
GOTO LOOP
:DONE
REN СОХРАНЯЕМ ВЫРЕЗАННОЕ В ФАЙЛЕ СО СЛЕДУЮЩИМ НОМЕРОМ
REN DX.ALG %FOP%

Страшно? На самом деле, не очень. Во-первых, если Вы хоть как-то хотите автоматизировать свою работу на компьютере выучить несложные команды DOS/Windows, придется. Во-вторых, все эти можные WEB-разработки базируются на языках, которые выросли из этих простых командных. И, если эти убогие дизайнеры справляются, то уж инженеру - сам бог велел.
***

Ну, хорошо, мы научились соединять "вырезатели-добавляторы" в цепочки, а дальше? Весь этот эквилибр нас так и не приблизил к переходу количества наших огрызков в игровое качество.
Так, для этого я и сделал их такими простыми. Чтобы каждый мог создавать их в нужном количестве.
Здесь буду выкладывать кубики и сборки из их, понадобившиеся при редактировании базы STARGRUNT II до тех пор, пока не буду способен сделать конструктор по-мощнее.
***

Сразу могу сказать, что, приходящие на ум в первую очередь, команды копирования/перемещения узлов "дерева" оказались на редкость бесполезными.
***

Изначально у нас только одна (ОБЩАЯ) команда - текстовый редактор нашей ОС, в которой мы можем править файлы данных (и скриптов). Длина файла с базой данных - около 11200 строк (сколько "листьев", пока не знаю).
Для "нормального" программиста использование редактора очевидно: он использует его только в "безопасном месте" своего программно-аппаратного комплекса. Его любимый "обезьянник" позволяет править программу (и ее данные) и, по мере готовности, запускать-отлаживать ее, время от времени сохраняя результат на диске.
В моем примере DOS-овского УППК-скрипта тоже все очевидно и без проблем. Видно, что редактор (древний NE) не конфликтует с остальными программами по еще более простой, чем наличие умного "обезьянника", причине - чтобы УУПК продолжила работу, ne должен закончить свою. Единственная возможная провокация - испортить в редакторе сам скрипт.
В Windows-окошках (или в моем первоначпльном HTML) все гораздо неудобнее. Окно редактора постоянно болтается "где-то рядом" и нет никакой гарантии, что то, что мы в нем видим, соответствует данным или скриптам, которые будут прочитаны нашими программами, тем более, с дисков сервера.
***

ЛИРИЧЕСКОЕ ОТСТУПЛЕНИЕ. В чем отличие текстового редактора от текстовой игры?
Если посмотреть на последние, то можно видеть два вида операций: над синтаксически значимыми единицами - буквами, словами, абзацами, блоками..; другие - над смысловыми - попадающими под шаблоны поиска...
Можно даже заметить, что автоматизация первых идет по "пути интерпретаторов" (тот же vim), а вторых - по "пути компиляторов" (ср. awk). Т.е. в первые представляют из себя ОБЩИЕ программы со все более усложняющимся набором команд, а вторые - все усложняющиеся ПОСЛЕДОВАТЕЛЬНЫЕ программы-фильтры.
А игры? А в них между синтаксисом и семантикой существует баланс, избавляющий игрока от поиска "по всему документу" и ограничивающий его поля зрения законченным семантико-семантически значимым объектом.
КОНЕЦ ЛИРИЧЕСКОГО ОТСТУПЛЕНИЯ.
avatar
Gudleifr
Admin

Сообщения : 879
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.02. МАЛЕВИЧ, ГОВОРИТЕ?

Сообщение автор Gudleifr в Вс Апр 15, 2018 9:29 am

Как сделать подобный цикл играющим?

Вспомним игру X-Com ТЕМА #117. Внешний цикл игры - простой экономический симулятор, какой мы во второй главе первой части в пару десятков строк писали. Только с двумя нетривиальными дополнениями: то и дело приходилось отвлекаться на проведение тактических боев, а, возвращаясь с войны, мы видели, что что-то поменялось - перед нашей "экономикой" ставились новые задачи, появлялись новые возможности.

Необходим ли для такой организации игры компьютер? Да, вроде, на первый взгляд, нет. Взять ту же "Пандору" ТЕМА #28, АБЗАЦ #193. Такой же внешний цикл - перебор посещаемых планет, прерываемый высадками. Кое-какие происшествия. Хозяйственные проблемы.

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

Может ли этими качествами обладать цикл разработки, записанный в виде дурацкого командного файла? А почему нет?


Последний раз редактировалось: Gudleifr (Сб Апр 21, 2018 9:16 am), всего редактировалось 1 раз(а)
avatar
Gudleifr
Admin

Сообщения : 879
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.02. МАЛЕВИЧ, ГОВОРИТЕ?

Сообщение автор Gudleifr в Сб Апр 21, 2018 9:16 am

Какого же рода должны быть позвонки этого скелета?

Жуков описывает блоки, как порции процесса обработки информации (относятся к решению задачи).
Кнут - как единицы соответствия кода документации (относятся к программированию решения).
В командных файлах блоки определяются требованиями Операционной Системы (запуск запрограммированного решения).

Можно ли совместить все три подхода? К сожалению, нет, взаимного соответствия одних блоков другим не просматривается. Скорее, наоборот, они описывают практически не пересекающиеся фрагменты кода. А случись взаимопроникновение, оно означает лишь потерю управления. Как, например, в предыдущей главе объекты JavaScript (детали запуска) мешали нам структурировать (программировать) решение.

Можно ли рассматривать конкретный кусочек задачи как однозначно относящийся к блокам определенного типа, точнее, к одному из этапов программного решения? Или его можно с разной степенью успешности решать на любом этапе?

Например, в прошлой главе, написание программы общей операции явно относилось к программированию решения, а замена ее набором последовательных операций - к собственно решению.

Когда-то пытались свести все к одной блок-схеме, придумав обозначения для всех возможых операций: вычислительных, управляющих, ручных, аппаратно-зависимых... Однако, правильным, видимо, является нахождение отдельного наглядного изобразительного решения для каждого нового проекта. Впрочем, об этом я писал еще в конце главы "про королей и капусту".
avatar
Gudleifr
Admin

Сообщения : 879
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.02. МАЛЕВИЧ, ГОВОРИТЕ?

Сообщение автор Gudleifr в Пн Май 21, 2018 7:59 pm

СКРИПТЫ ПО ВИНДОСОВСКИ

Т.к. я окровенно слаб в JavaScript, то пытаясь перейти с DOS-скриптов на мастдайные, я попытался найти какую-нибудь умную книжку. Облом за обломом. В большинстве рассматривался лишь простейший оживляж HTML-файлов, а в очень редких оставшихся - рассказывалось, как пересчитать системные директории и достучаться до сетевых принтеров... Наконец, в одной из книжек А.В.Попова я нашел способ организации простого интерфейса с пользователем и файловой системой на примере поэтапного создания записной книжки. Немного покопипастил и причесал...

Сначала Автор представлял эту книжку в виде текстового файла book.txt:

Потапов|Сергей|55-55-55|Моховая|3|10|Без примечаний
Попов|Андрей|56-56-56|Ленина|3|5|Без примечаний
Иванов|Иван|17-17-17|Садовая|4|6|Очень хороший человек
Казаков|Сергей|24-19-68|Полежаева|101|22|Тоже очень хороший человек

Скрипт SortName.js, выдающий ее в отсортированном виде, приведен ниже. Обратите внимание на кучу "системных объектов" и на то, что в JavaScript (в отличие от VBScript) приходится запоминать числовые значения констант системных вызовов.
Файлы .js (как и .vbs - для VBScript - или .wsf - для нескольких скриптов зараз) запускаются как обычные командные - набиванием имени в командной строке (если хочется, с явным указанием запускателя - cscript или wscript) или нажатием на иконку. CMD- и WIN-запускатели немного отличаются: первый умеет работать с DOS-потоками, а второй - выводит исключительно в окошки. Нам - без разницы.
И, конечно, никакой компиляции или установки специальных утилит не требуется. Мастдай уже давно это умеет.

function PrintPerson(Person) {
FOut.WriteLine("Фамилия: "+Person[0]);
FOut.WriteLine("Имя: "+Person[1]);
FOut.WriteLine("Телефон: "+Person[2]);
FOut.WriteLine("Улица: "+Person[3]);
FOut.WriteLine("Дом: "+Person[4]);
FOut.WriteLine("Кв.: "+Person[5]);
FOut.WriteLine("Заметки: "+Person[6]);
FOut.WriteLine("*****")
}
function SortLastName(Pers1, Pers2) {
if (Pers1[0]<Pers2[0]) return -1;
else if (Pers1[0]==Pers2[0]) return 0;
else return 1
}
var WshShell = WScript.CreateObject("WScript.Shell");
var BasePath = WshShell.CurrentDirectory+"\\";
var FSO = WScript.CreateObject("Scripting.FileSystemObject");
var FBook = FSO.OpenTextFile(BasePath+"book.txt", 1, true);
var PersonArr = [];
while (!FBook.AtEndOfStream)
PersonArr[PersonArr.length] = FBook.ReadLine().split("|");
FBook.Close();
var PathOut = BasePath+"out.txt";
var FOut = FSO.OpenTextFile(PathOut, 2, true);
FOut.WriteLine("Сортировка по фамилии");
FOut.WriteLine("--------------------");
FOut.WriteLine("");
PersonArr.sort(SortLastName);
for (var i=0; i<PersonArr.length; i++) PrintPerson(PersonArr[i]);
FOut.WriteLine("");
FOut.WriteLine("Всего записей: "+PersonArr.length);
FOut.Close();
WshShell.Run("notepad "+PathOut, 1);

Затем Автор переносит свою записную книжку в XML-формат (жуткая жуть), что нам не надо. Мы продолжим работать с текстовым форматом.
Немного усложним. FindAndDelRecord.wsf - скрипт для удаления строки из записной книжки. Он .wsf потому, что ф-ии InputBox в JavaScript нет, приходится прицепить кусочек VBScript.

<job id="FindAndDel">
<script language="VBScript">
Function InputName
InputName = InputBox("Введите фамилию для удаления:", "Записная книжка")
End Function
</script>
<script language="JScript">
var WshShell = WScript.CreateObject("WScript.Shell");
var BasePath = WshShell.CurrentDirectory+"\\";
var FSO = WScript.CreateObject("Scripting.FileSystemObject");
var PathBook = BasePath+"book.txt";
var LastName = InputName();
var Res, FBook, PersonArr, Person, FOut;
if (LastName && LastName.length) {
Res = WshShell.Popup("Удалить фамилию "+LastName+" из \n"+
PathBook+"?", 0, "Записная книжка", 32+4);
if (Res==6) {
FBook = FSO.OpenTextFile(PathBook, 1, true);
PersonArr = [];
Res = 0;
while (!FBook.AtEndOfStream) {
Person = FBook.ReadLine();
if (Res || (LastName!=Person.split("|")[0]))
PersonArr[PersonArr.length] = Person
else Res = 1 }
FBook.Close();
FOut = FSO.OpenTextFile(PathBook, 2, true);
for (var i=0; i<PersonArr.length; i++) FOut.WriteLine(PersonArr[i]);
FOut.Close();
if (Res) WshShell.Popup("Запись удалена!", 0, "Записная книжка", 64);
else WshShell.Popup("Фамилия "+LastName+
" не найдена в записной книжке!", 0, "Записная книжка", 64) } }
</script>
</job>

После этого Автор объединил эти кусочки общей оболочкой, что нас, собственно и интересует. В отличие от предыдущих скриптов, работающих самостоятельно, тут, прежде чем запускать, нужно сначала набить все файлы-библиотеки. Во-первых, "общая билиотека" - Usage.js.

var WshShell, BasePath, FSO, FBook, PathBook, FOut, PersonArr, Person, LastName, Res;
function PrintPerson(Person) {
FOut.WriteLine("Фамилия: "+Person[0]);
FOut.WriteLine("Имя: "+Person[1]);
FOut.WriteLine("Телефон: "+Person[2]);
FOut.WriteLine("Улица: "+Person[3]);
FOut.WriteLine("Дом: "+Person[4]);
FOut.WriteLine("Кв.: "+Person[5]);
FOut.WriteLine("Заметки: "+Person[6]);
FOut.WriteLine("*****")
}
function SortLastName(Pers1, Pers2) {
if (Pers1[0]<Pers2[0]) return -1;
else if (Pers1[0]==Pers2[0]) return 0;
else return 1
}
function InitPath() {
WshShell = WScript.CreateObject("WScript.Shell");
BasePath = WshShell.CurrentDirectory+"\\";
FSO = WScript.CreateObject("Scripting.FileSystemObject")
}
function MakeOut(Top, Bottom) {
var PathOut = BasePath+"out.txt";
FOut = FSO.OpenTextFile(PathOut, 2, true);
FOut.WriteLine(Top);
FOut.WriteLine("--------------------");
FOut.WriteLine("");
PersonArr.sort(SortLastName);
for (var i=0; i<PersonArr.length; i++) PrintPerson(PersonArr[i]);
FOut.WriteLine("");
FOut.WriteLine(Bottom+": "+PersonArr.length);
FOut.Close();
WshShell.Run("notepad "+PathOut, 1);
}

Далее - библиотека второго уровня - PhoneBook.wsf, объединяющая (поэтому и .wsf) в себе уже введенные операции (и, дополнительно, еще пару). Т.к. я не стал отказываться от эффективности в пользу единообразия, то не запутайтесь, где записи (Person) храняться в виде массивов, а где - в виде строк. Обратите внимание на получение ф-иями параметров из командной строки - WScript.Arguments.Named.

<package>
<job id="SortName">
<script language="JScript" src="usage.js"/>
<script language="JScript">
InitPath();
FBook = FSO.OpenTextFile(BasePath+"book.txt", 1, true);
PersonArr = [];
while (!FBook.AtEndOfStream)
PersonArr[PersonArr.length] = FBook.ReadLine().split("|");
FBook.Close();
MakeOut("Список всех записей, сортировка по фамилии","Всего записей");
</script>
</job>
<job id="FindName">
<script language="JScript" src="usage.js"/>
<script language="JScript">
LastName = WScript.Arguments.Named("X");
InitPath();
FBook = FSO.OpenTextFile(BasePath+"book.txt", 1, true);
PersonArr = [];
while (!FBook.AtEndOfStream) {
Person = FBook.ReadLine().split("|");
if (LastName==Person[0]) PersonArr[PersonArr.length] = Person }
FBook.Close();
if (PersonArr.length) MakeOut("Поиск записей", "Всего найдено")
else WshShell.Popup("Фамилия "+ LastName+ " не найдена!", 0,
"Записная книжка", 64)
</script>
</job>
<job id="DelRec">
<script language="JScript" src="usage.js"/>
<script language="JScript">
LastName = WScript.Arguments.Named("X");
if (LastName && LastName.length) {
InitPath();
PathBook = BasePath+"book.txt";
Res = WshShell.Popup("Удалить фамилию "+LastName+" из \n"+
PathBook+"?", 0, "Записная книжка", 32+4);
if (Res==6) {
FBook = FSO.OpenTextFile(PathBook, 1, true);
PersonArr = [];
Res = 0;
while (!FBook.AtEndOfStream) {
Person = FBook.ReadLine();
if (Res || (LastName!=Person.split("|")[0]))
PersonArr[PersonArr.length] = Person
else Res = 1 }
FBook.Close();
FOut = FSO.OpenTextFile(PathBook, 2, true);
for (var i=0; i<PersonArr.length; i++) FOut.WriteLine(PersonArr[i]);
FOut.Close();
if (Res) WshShell.Popup("Запись удалена!", 0, "Записная книжка", 64);
else WshShell.Popup("Фамилия "+LastName+
" не найдена в записной книжке!", 0, "Записная книжка", 64) } }
</script>
</job>
<job id="AddRec">
<script language="JScript" src="Usage.js"/>
<script language="JScript">
Person = WScript.Arguments.Named("X");
InitPath();
PathBook = BasePath+"book.txt";
FBook = FSO.OpenTextFile(PathBook, 8, true);
FBook.WriteLine(Person);
FBook.Close()
WshShell.Popup("Новая запись\n\n"+Person+"\n\nдобавлена в файл "+
PathBook, 0, "Записная книжка", 64)
</script>
</job>
<job id="Test">
<script language="JScript">
WScript.Echo("Параметр2: "+WScript.Arguments.Named("X"))
</script>
</job>
</package>

Отдельно - VBScript-кусочек WSHInputBox.vbs для InputBox().

Function WSHInputBox(Message,Title)
'Выводим диалоговое окно со строкой ввода
WSHInputBox = InputBox(Message,Title)
End Function

Первый вариант оболочки - для работы из консоли. Команды вводятся ключами вызова.

<job id="ArgMenu">
<runtime>
<description>
Сценарий для работы с телефонной книжкой
</description>
<named name="L" helpstring="Просмотр содержимого книжки" type="simple" required="false"/>
<named name="F" helpstring="Поиск по фамилии" type="simple" required="false"/>
<named name="A" helpstring="Добавление записи" type="simple" required="false"/>
<named name="D" helpstring="Удаление записи" type="simple" required="false"/>
</runtime>
<script language="VBScript" src="WSHInputBox.vbs"/>
<script language="JScript">
var Res, Person;
var WshShell = WScript.CreateObject("WScript.Shell");
if ((WScript.Arguments.Named.Exists("L")) ||
(WScript.Arguments.Named.Exists("l")))
WshShell.Run("wscript PhoneBook.wsf //Job:SortName");
else if ((WScript.Arguments.Named.Exists("F")) ||
(WScript.Arguments.Named.Exists("f"))) {
Person = WSHInputBox("Введите фамилию для поиска:","Записная книжка");
if (Person && Person.length)
WshShell.Run("wscript PhoneBook.wsf //Job:FindName /X:\""+Person+"\"") }
else if ((WScript.Arguments.Named.Exists("A")) ||
(WScript.Arguments.Named.Exists("a"))) {
Res = WshShell.Popup("Добавить запись?", 0,
"Записная книжка", 32+4);
if (Res==6) {
Person = [];
Person[0] = WSHInputBox("Введите фамилию","Добавление записи");
Person[1] = WSHInputBox("Введите имя","Добавление записи");
Person[2] = WSHInputBox("Введите телефон","Добавление записи");
Person[3] = WSHInputBox("Введите улицу","Добавление записи");
Person[4] = WSHInputBox("Введите дом","Добавление записи");
Person[5] = WSHInputBox("Введите квартиру","Добавление записи");
Person[6] = WSHInputBox("Введите примечание","Добавление записи");
WshShell.Run("wscript PhoneBook.wsf //Job:AddRec /X:\""+
Person.join("|")+"\"") } }
else if ((WScript.Arguments.Named.Exists("D")) ||
(WScript.Arguments.Named.Exists("d"))) {
Person = WSHInputBox("Введите фамилию для поиска:","Записная книжка");
if (Person && Person.length)
WshShell.Run("wscript PhoneBook.wsf //Job:DelRec /X:\""+Person+"\"") }
else WScript.Arguments.ShowUsage()
</script>
</job>

Конечно, команды можно вводить так же, как мы вводили фамилии, но это совсем не интересно. Поэтому сразу перейдем к HTML. За графическое прелставление нашей программы будет отвечать файл Phone.htm:

<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Форма для записной книжки</title>
</head><body bgcolor="silver" scroll="no">
<form name="MainForm">
<table><tr><td>Фамилия</td>
<td><input type="text" name="txtLastName" size="50"></td></tr>
<tr><td>Имя</td>
<td><input type="text" name="txtName" size="50"></td></tr>
<tr><td>Телефон</td>
<td><input type="text" name="txtPhone" size="15"></td></tr>
<tr><td>Улица</td>
<td><input type="text" name="txtStreet" size="50"></td></tr>
<tr><td>Дом</td>
<td><input type="text" name="txtHouse" size="10"></td></tr>
<tr><td>Кв.</td>
<td><input type="text" name="txtApp" size="5"></td></tr><tr>
<td>Примечание</td>
<td><input type="text" name="txtNote" size="80"></td>
</tr></table><br>
<input type="button" value="&lt;&lt;" name="btnFirst">
<input type="button" value="&lt;" name="btnPrevious">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<input type="button" value="Новая запись" name="btnNew">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<input type="button" value="Записать" name="btnSave">
<input type="button" value="Отменить" name="btnCancel">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<input type="button" value="Удалить" name="btnDelete">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<input type="button" value="&gt;" name="btnNext">
<input type="button" value="&gt;&gt;" name="btnFinal">
</form></body></html>

Теперь напишем программу, которая согласиться считать эту экранную форму своим интерфейсом - IEPhoneBook.wsf.

<job id="IEPhone">
<script language="JScript" src="usage.js"/>
<script language="JScript">
var IsQuit, IsNotOk, Doc, Num;
function SetData () {
if (Num==PersonArr.length) Num--;
Doc.all.txtLastName.value = PersonArr[Num][0];
Doc.all.txtName.value = PersonArr[Num][1];
Doc.all.txtPhone.value = PersonArr[Num][2];
Doc.all.txtStreet.value = PersonArr[Num][3];
Doc.all.txtHouse.value = PersonArr[Num][4];
Doc.all.txtApp.value = PersonArr[Num][5];
Doc.all.txtNote.value = PersonArr[Num][6];
IsNotOK = false;
Doc.title = "Запись #"+(Num+1)
}
function RefreshData() {
FBook = FSO.OpenTextFile(PathBook, 1, true);
PersonArr = [];
while (!FBook.AtEndOfStream)
PersonArr[PersonArr.length] = FBook.ReadLine().split("|");
FBook.Close();
if (!PersonArr.length) {
PersonArr[0] = ["", "", "", "", "", "", ""];
Num = 0; }
SetData()
}
function SaveData(N) {
if (IsNotOk) {
PersonArr[Num][0] = Doc.all.txtLastName.value;
PersonArr[Num][1] = Doc.all.txtName.value;
PersonArr[Num][2] = Doc.all.txtPhone.value;
PersonArr[Num][3] = Doc.all.txtStreet.value;
PersonArr[Num][4] = Doc.all.txtHouse.value;
PersonArr[Num][5] = Doc.all.txtApp.value;
PersonArr[Num][6] = Doc.all.txtNote.value;
FOut = FSO.OpenTextFile(PathBook, 2, true);
for (var i=0; i<PersonArr.length; i++) FOut.WriteLine(PersonArr[i].join("|"));
FOut.Close() }
Num = N;
SetData()
}
function ChangeData() {
IsNotOk = true;
Doc.title = "Редактируется запись #"+(Num+1)
}
function ie_DocumentComplete() {
Doc = ie.Document;
Doc.all.btnSave.onclick = function() { SaveData(Num) };
Doc.all.btnCancel.onclick = function() { IsNotOk = false; SaveData(Num) };
Doc.all.btnFirst.onclick = function() { SaveData(0) };
Doc.all.btnPrevious.onclick = function() { SaveData(Num?Num-1:0) };
Doc.all.btnNew.onclick = function() {
PersonArr[PersonArr.length] = ["", "", "", "", "", "", ""];
SaveData(PersonArr.length) };
Doc.all.btnDelete.onclick = function() {
ie.Visible = false;
WshShell.Run("wscript PhoneBook.wsf //Job:DelRec /X:\""+
PersonArr[Num][0]+"\"", 0, true);
ie.Visible = true;
RefreshData() }
Doc.all.btnNext.onclick = function() { SaveData(Num+1) };
Doc.all.btnFinal.onclick = function() { SaveData(PersonArr.length) };
Doc.all.txtLastName.onchange = ChangeData;
Doc.all.txtName.onchange = ChangeData;
Doc.all.txtPhone.onchange = ChangeData;
Doc.all.txtStreet.onchange = ChangeData;
Doc.all.txtHouse.onchange = ChangeData;
Doc.all.txtApp.onchange = ChangeData;
Doc.all.txtNote.onchange = ChangeData;
Num = 0;
RefreshData();
ie.Visible = true;
}
function ie_OnQuit() {
IsQuit = true
}
InitPath();
PathBook = BasePath+"book.txt";
PathHTML = BasePath+"Phone.htm";
ie = WScript.CreateObject("InternetExplorer.Application", "ie_");
ie.AddressBar = false;
ie.FullScreen = false;
ie.MenuBar = false;
ie.Resizable = false;
ie.StatusBar = false;
ie.ToolBar = false;
ie.Height = 350;
ie.Width = 780;
IsQuit = false;
ie.Navigate(PathHTML);
while (!IsQuit) WScript.Sleep(100)
</script></job>

Нужна ли эта цепочка: библиотеки_операций - библиотека_команд - оболочка? Конечно, нет. Автор, например, свою HTML-оболочку полностью написал заново (.js). Я же, как дурак, старался сохранить хоть какую-то преемственность примеров, плюс, подчеркнуть связь WHS-скриптов с Операционной Системой.

Что дальше? Читать книжки по правильному ООП в JavaScript, изучать библиотеки системных объектов... Главное, у нас теперь есть способ прицепить к нашим учебным программам хоть какой-то интерфейс и худо-бедно сохранять результаты работы в виде файлов. Как говорят строители, нулевой цикл пройден.
avatar
Gudleifr
Admin

Сообщения : 879
Дата регистрации : 2017-03-29

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: 02.02. МАЛЕВИЧ, ГОВОРИТЕ?

Сообщение автор Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения