Создание программы-интерпретатора блок-схем

 

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ

Государственное образовательное учреждение высшего профессионального образования

«Ижевский государственный технический университет»

Кафедра АСОИУ










ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к курсовой работе

по дисциплине «Промышленная логистика»

на тему «Создание программы-интерпретатора блок-схем»




Проектанты:

студенты гр. 8-78-5М.К. Овсянников, С.А. Сенилов

Руководитель

преподаватель кафедры АСОИУМ.С. Созыкина




Ижевск 2012

Содержание


1. Аналитический обзор существующих программ-редакторов схем

1.1 Microsoft Office Visio 2007

1.2 Редактор блок-схем

1.3 FCEditor

1.4 Вывод по аналитическому обзору

2. Выбор технических средств

3. Диаграммы

3.1 Функциональная модель

3.2 Диаграмма потоков данных

3.3 Диаграмма прецедентов

4. Математическое описание программы

4.1 Описание модели данных

4.2 Математическое описание используемых моделей данных

4.3 Описание структур данных

4.4 Алгоритм программы

4.5 Диаграмма классов

5. Описание интерпретатора использованного в программе

5.1 Варианты использования

5.2 Возможности Jint

5.3 Описание основных возможностей языка JavaScript

5.3.1 Вывод данных

5.3.2 Переменные

5.3.3 Базовые типы

5.3.4 Операторы

5.3.5 Массивы

5.3.6 Функции

5.3.7 Циклы

6. Описание системы и руководство пользователя

6.1 Описание главного меню

6.2 Описание панели инструментов и операций

6.3 Описание вставки новых блоков

6.4 Выполнение кода блок схемы

7. Примеры программ созданных в редакторе

7.1 Решение квадратного уравнения

7.2 Сортировка массива пузырьком

7.3 Среднее значение элементов массива

Заключение

Приложение А. Исходный текст программы редактора схем

Приложение Б. XML файл генерируемый программой

Список литературы


Введение


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

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

Их применение значительно облегчало восприятие и анализ программы. Двумерное представление программы более ясно отражало ее структуру. Применение блок- схем позволяло быстрее и качественнее разрабатывать и отлаживать программы.

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

Естественным развитием данной ситуации является объединение двух подходов в описании программ: в виде текста и блок-схемы. Результатом такого объединения является понятие визуального программирования. Под ним понимается способ описания алгоритма решения задачи в графическом виде, соединяющий достоинства текста и блок-схем программ.

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

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

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

программа редактор схема интерпретатор

1. Аналитический обзор существующих программ-редакторов схем


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


.1 Microsoft Office Visio 2007

Office Visio 2007 - программа построения чертежей и диаграмм, помогающая специалистам сферы ИТ и сферы бизнеса визуализировать, исследовать и распространять сложную информацию[1]. Трудный для понимания текст и таблицы можно представить в виде простых и наглядных диаграмм Visio. Вместо статичных рисунков пользователи создают тесно связанные с данными диаграммы Visio, которые отображают данные, легко обновляются и позволяют заметно повысить производительность работы. Широкий спектр диаграмм Office Visio 2007 помогает лучше понять информацию об организационных системах, ресурсах и процессах всего предприятия, принимать решения на основе этой информации и обмениваться ею.Office Visio 2007 обладает следующими преимуществами:

. Визуализация, исследование и публикация систем, ресурсов, процессов и связанных с ними данных[2]. Широкий выбор типов схем Office Visio 2007 обеспечивает эффективную визуализацию, исследование и публикацию процессов, ресурсов, систем и связанных с ними данных.

. Визуализация сложной информации путем вывода данных в схемах и выполнение соответствующих действий. Визуализация данных в диаграммах позволяет лучше понять суть данных и выполнять необходимые действия в зависимости от результатов анализа. Используя средство Microsoft Office Visio 2007 «Рисунки, связанные с данными», можно изображать данные в любой диаграмме в виде текста, элементов данных, значков и цветовых обозначений.

. Быстрое создание диаграмм благодаря автоматическому подключению к фигурам Visio. В Office Visio 2007 имеется новая функция автоматического соединения, которая может автоматически подключать, размещать и выравнивать фигуры на схеме, облегчая работу пользователя. Достаточно перетащить фигуру на страницу документа и расположить ее над одной из синих стрелок, которые находятся над фигурой, уже размещенной на странице.

. Представление комплексных данных с использованием новых шаблонов и фигур. представления данных благодаря новым и усовершенствованным шаблонам и фигурам. Например, в выпуске Office Visio Профессиональный 2007 можно составлять схемы процессов ИТ-служб с помощью нового шаблона ITIL (Information Technology Infrastructure Library),создавать диаграммы на основе экономичной методологии и визуализировать более эффективные производственные процессы при помощи нового шаблона схемы потока создания стоимости.

. Повышение производительности благодаря интеграции схем с данными из разных источников. Источники комплексных визуальных, текстовых и числовых данных. Диаграммы, подключенные к данным, обеспечивают визуальный контекст для данных и дают полное представление о системе или процессе. Связь схем с данными из различных источников стала проще благодаря функции связывания данных в Office Visio Профессиональный 2007. Привязка данных к фигурам диаграммы выполняется с помощью нового мастера автоматического связывания.

. Исследование данных для отслеживания тенденций, выявления проблем и пометки исключений с помощью сводных схем. Шаблон сводной схемы позволяет наглядно представлять и анализировать бизнес-данные в Office Visio Профессиональный 2007 в иерархической форме в виде групп и итогов данных. Имеется возможность детализировать комплексные данные, отображать информацию с помощью средства «Рисунки, связанные с данными», динамически создавать различные представления данных и лучше понимать сложную информацию. Сводные схемы можно вставлять в любую диаграмму Visio, чтобы получать доступ к показателям и отчетам, которые помогут отслеживать текущее состояние процесса или системы. Сводные схемы создаются путем подключения к различным источникам данных, таким как Microsoft Office SharePoint Server 2007, Microsoft Office Project 2007 и Microsoft Office Excel 2007. Возможность создания наглядных отчетов программ Office SharePoint Server 2007 и Office Project 2007 в форме сводной схемы повышает эффективность контроля ресурсов и проектов, управляемых с помощью этих программ.

. Эффективное распространение информации с помощью профессионально оформленных схем. Для создания диаграмм Visio профессионального качества достаточно выбрать цвет или эффект (текст, заливку, тень, линии, формат соединителей) для всей диаграммы с использованием новой функции «Тема». На выбор в Visio предлагается ряд встроенных тем, но можно создавать и собственные темы. В Office Visio 2007 используются те же встроенные темы, что и в других программах системы Microsoft Office 2007.


1.2 Редактор блок-схем


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

Системные требования программы очень скромные и она запускается практически на любом компьютере с любой версией Windows .

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

. Использование шаблонов при создании блок-схем.

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

. Экспорт блок-схем в процедуры и функции языков программирования.

. Экспорт блок-схем в различные графические форматы.


1.3 FCEditor


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

. импорт схемы из программного кода;

. автоматическое выравнивание блоков и стрелок;

. возможность изменения типа блоков;

. копирование и вставка блоков схемы;

. отдельная схема для каждой процедуры;

. возможность вставки разрывов страниц;

. экспорт схемы в графический файл;

. экспорт схемы в код.

Таким образом, несмотря на небольшой вес FCEditor является достаточно многофункциональной программой-редактором схем.


1.4 Вывод по аналитическому обзору


Рассмотрев существующие программы-редакторы схем, мы можем их обобщить, каждая из них:

. Может использовать шаблоны для создания схем.

. Может экспортировать созданную схему в различные форматы.

. Обладает автоматической «подгонкой» блоков и стрелок.

. Может создавать разные типы схем.

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

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


2. Выбор технических средств


Программа написана на платформе .NET Framework 3.5 в интегрированной среде разработки Visual Studio 2010 Professional.

Технические средства необходимые для разработки программы выбираем исходя из системных требований Visual Studio 2010 Professional.Studio 2010 можно установить в следующих операционных системах:

. windows XP (x86) с пакетом обновления 3 (SP3) - все выпуски, кроме Starter;

. windows Vista (x86 и x64) с пакетом обновления 1 (SP1) - все выпуски, кроме Starter;

. windows 7 (x86 и x64);

. windows Server 2003 (x86 и x64) с пакетом обновления 2 (SP2);

5. windows Server 2003 R2 (x86 и x64);

6. windows Server 2008 (x86 и x64) с пакетом обновления 2 (SP2);

. windows Server 2008 R2 (x64).

Поддерживаемые архитектуры:

.32-разрядная (x86);

. 64-разрядная (x64).

Требования к оборудованию:

. процессор с частотой 1,6 ГГц или выше;

. 1024 МБ ОЗУ;

. 3 ГБ свободного места на диске;

. жесткий диск со скоростью 5400 об/мин;

. видеоадаптер с поддержкой DirectX 9 и разрешением 1280 x 1024 (или более высоким);

. дисковод DVD-ROM.

Технические средства необходимые для запуска программы выбираем исходя из системных требований .NET Framework 3.5:

1. Операционные системы: Windows Server 2003, Windows Server 2008, Windows Vista, Windows 7, Windows XP.

2. Процессор: Pentium с тактовой частотой 400 MГц или аналогичный процессор (рекомендуется Pentium с тактовой частотой 1ГГц или аналогичный процессор).

. ОЗУ: не менее 96 МБ (рекомендуется 256 МБ).

. Жесткий диск: может потребоваться до 500 МБ доступного дискового пространства.

. Дисковод для компакт-дисков или DVD-дисков: не требуется.

. Экран: разрешение 800 x 600, 256 цветов (рекомендуется разрешение 1024 x 768, 32-разрядный)).


3 Моделирование процессов системы


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

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

Объектные методики рассматривают моделируемую организацию как набор взаимодействующих объектов - производственных единиц. Объект определяется как осязаемая реальность - предмет или явление, имеющие четко определяемое поведение. Целью применения данной методики является выделение объектов, составляющих организацию, и распределение между ними ответственностей за выполняемые действия.

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

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


3.1 Разработка функциональной модели системы


Методология функционального моделирования IDEF0 является достаточно простым инструментом, который позволяет разработчикам корпоративных информационных систем изучить сферу деятельности заказчика и решать задачи по повышению эффективности этой деятельности[3].

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

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

В ходе проектирования структуры интерфейса системы с использованием стандарта IDEF0 мы получили следующие функциональные блоки:

1. Блок А0: Создать программу с помощью визуального редактирования её блок-схемы(рисунок 3.1).

. Блок А1: Подготовить условия для создания схемы (рисунок 3.2).

. Блок А2: Разработать бета-версию схемы (рисунок 3.2).

. Блок А3: Редактировать блок-схему (рисунок 3.2).

. Блок А11: Согласовать с заказчиков условия создания блок-схемы (рисунок 3.3).

. Блок А12: Описать требования к реализации задачи (рисунок 3.3).

. Блок А13: Формализовать описание задачи (рисунок 3.3).

. Блок А21: Определить список переменных, продседур и функций, которые будут использоваться в программе (рисунок 3.4).

. Блок А22: Построить структуру схемы (рисунок 3.4).

10. Блок А23: Подписать блоки в схеме (рисунок 3.4).

11. Блок А24: Создать тестовые примеры (рисунок 3.5).

. Блок А31: Запустить работу интерпретатора (рисунок 3.5).

. Блок А32: Определить соответствие выводимых данных результатам тестов (рисунок 3.5).



Рисунок. 3.1 - Контекстная диаграмма. Создать программу с помощью визуального редактирования её блок-схемы



Рисунок 3.2 - Декомпозиция контекстной диаграммы. Создать программу с помощью визуального редактирования её блок-схемы



Рисунок 3.3 - Диаграмма декомпозиции блока А1. Подготовить условия для создания блок-схемы


В данной системе диаграммы IDEF0 помогли выявить основные функции системы и нормативные документы с которыми нужно согласовываться при проектировании программы. Было выявлено что схема определенного типа может состоять только из некоторой совокупности блоков. Для этого блоки были разделены на классы.

В ходе проектирования схемы IDEF0 были выявлены основные функции будущей системы, которые были впоследствии реализованы в программе.


3.2 Диаграмма потоков данных

позволяет уже на стадии функционального моделирования определить базовые требования к данным[4]. На диаграмме потоков данных показываются работы, которые входят в состав описываемого бизнес-процесса, а также показываются входы и выходы каждой из работ. Данные входы и выходы представляют собой информационные, либо материальные потоки. При этом выходы одной работы могут являться входами для других. Наличие в диаграммах DFD элементов для описания источников, приемников и хранилищ данных позволяет более эффективно и наглядно описать процесс документооборота.

В данной системе с помощью DFD диаграммы были выявлены связи между некоторыми классами. Было выявлено, что схема доступная для редактирования может проверяться на любом этапе ее проектирования. Таким образом, процедура проверки корректности схем была встроена в класс окна ответственного за редактирование схемы. Было выявлено, что схемы нужно сохранять для последующего редактирования или в файл .jpg. Таким образом, мы выяснили, что вся схема должна быть сохранена в формат, отрывая который можно восстановить схему полностью. На основе полученного требования было принято решение использовать сериализацию объектов, т.е. сохранения всех объектов схемы и их состояний на жесткий диск. Для этого был выбран класс XmlSerializer, который позволяет сохранять состояние объектов в формате XML и затем восстанавливать объекты из этого формата. Для сохранения в .jpg была использована стандартная процедура сохранения изображения в файл.диаграмма представлена на рисунке

Рисунок 3.4 - Уровень А0 DFD-диаграммы. Спроектировать схему программы.

Существует так же альтернативный способ выявления требуемой функциональности системы. Выявить функциональность системы можно с помощью диаграммы прецедентов.


.3. Диаграмма прецедентов


Диаграммы прецедентов представляют собой один из пяти типов диаграмм, применяемых в UML для моделирования динамических аспектов системы[4]. Диаграммы прецедентов играют основную роль в моделировании поведения системы, подсистемы или класса. Каждая такая диаграмма показывает множество прецедентов, актеров и отношения между ними.

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

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


Диаграмма прецедентов представлена на рисунке 3.5.

Рисунок 3.5 - Диаграмма прецедентов


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

Если мы сравним результат применения диаграммы прецедентов с результатом применения диаграмм IDEF0 и DFD, то мы увидим что диаграммы IDEF0 и DFD помогли более точно сформулировать требования, предъявляемые к функциональности системы. В результате декомпозиции отдельных процессов основные элементы интерфейса программы были определены еще до написания программного кода.


4. Математическое описание программы


В ходе реализации выделенных выше функций необходимо описать алгоритмы и модели данных на формализованном или естественном языке.


4.1 Описание модели данных


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


Таблица 4.1 - Основные блоки, используемые в программе

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

4.2 Математическое описание используемых моделей данных


Списки используются для представления кортежей.

Кортеж - это конечная последовательность, возможно с повторениями, элементов некоторого множества E. Элементами кортежа могут быть числа, символы некоторого алфавита, точки плоскости и т.д. В более сложных случаях элементами кортежа, в свою очередь, могут быть также кортежи. Элементы, не являющиеся кортежами, называются атомами. Количество элементов в кортеже называется его длиной. Удобно рассматривать кортежи, не содержащие ни одного элемента. Такие кортежи называются пустыми. Длина пустого кортежа считается равной 0.

Элемент кортежа характеризуется своим номером в последовательности (кортежным номером) и содержанием, то есть элементом множества E. Если длина кортежа равна n, n>0, то кортеж S удобно рассматривать как отображение s множества N = {1 ,2, … n} в множество E. Таким образом, s(i) - это i-й элемент кортежа S.

Термин "список" используется как обобщающее название различных структур данных, используемых для представления кортежей в памяти компьютера. При представлении кортежа в памяти появляется еще одна характеристика элемента кортежа - его позиция в памяти. В некоторых случаях номер элемента в кортеже и его позиция в памяти связаны друг с другом арифметическими соотношениями таким образом, что по номеру легко вычисляется позиция и, наоборот, по позиции вычисляется номер. В других случаях связь между номерами и позициями задается "таблично" или осуществляется с помощью алгоритмических процедур. Множество позиций обозначим через P. Иногда удобно считать, что в множестве P имеется специальный элемент nil, указывающий на несуществующую область памяти. Таким образом, при рассмотрении того или иного списка мы имеем дело с тремя множествами E, N, P и с отображениями на этих множествах.

Типичными при работе со списками являются следующие операции:

. нахождение позиции элемента в памяти по его номеру в кортеже;

. нахождение позиции элемента, следующего в кортеже за элементом из заданной позиции;

. нахождение позиции элемента, предшествующего в кортеже элементу из заданной позиции;

. удаление элемента, находящегося в заданной позиции;

. вставка в кортеж нового элемента перед элементом, расположенным в заданной позиции;

. определение длины кортежа.


4.3 Описание структур данных


Для более глубокого понимания задачи следует описать используемые структуры данных математически.


Пусть - текущий блок,


где q - булева переменная, характеризующая тип блока: q= 0- блок является обычным блоком, q=1 -блок является блоком-веткой.


где - список блоков, принадлежащей данной ветке;

N-количество блоков, принадлежащей данной ветке;

Pointer(K)- указатель на ветку K , внутри которой находится блок.

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

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

Пусть Т<L, Pointer(K)> - точка вставки.

где L - это блок, после которого располагается точка;

Pointer(K)-Указатель на ветвь, внутри которой находится блок соответствующий точке вставки.


4.4 Алгоритм программы


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

В программе позиции блоков и точек вставки рассчитываются каждый раз заново при изменении схемы. Точки вставки так же генерируются каждый раз заново при изменении схемы. Для каждой ветки с помощью рекурсивной процедуры, которая обходит все вложенные блоки, рассчитывается ее общий размер, т.е. размер с учетом всех вложенных блоков. Затем блоки размещаются на схеме, выравнивание идет сверху вниз, слева направо.

При удалении блока определяется ветка, которой принадлежит этот блок, и из списка элементов этой ветки удаляется соответствующий блок . Координаты блоков схемы рассчитываются заново.


4.5 Диаграмма классов


На диаграмме классов представлено подробное описание классов использующихся в программе.

Сначала рассмотрим классы блоков. На рисунке 4.1 приведена диаграмма классов блоков.

Главный блок (ChartMainBlock) реализует метод сохранения схемы. В программе схема сохраняется в XML формат. Для этого был выбран класс XmlSerializer из пространства имен System.Xml.Serialization.

Пространство имен System.Xml.Serialization содержит классы, используемые для сериализации объектов в документы или потоки формата XML.

Центральным классом в пространстве имен является класс XmlSerializer, который позволяет сохранять состояние объектов в формате XML и затем восстанавливать объекты из этого формата. XmlSerializer сериализует и десериализует объекты в документы XML и из них. XmlSerializer позволяет контролировать способ кодирования объектов в XML. Пример XML файла сгенерированного программой можно посмотреть в приложении Б.

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

public abstract class Block

{List<Block> Items;Block Branch;

...

}

Блок определенного типа реализует только собственный метод отрисовки, все остальное он наследует от абстрактного класса Block.

public class RegularBLock : Block

{

...override void Draw(Graphics g) { ... }

...

}


Рисунок 4.1 - Диаграмма классов блоков.


Далее рассмотрим класс, представляющий всю блок-схему. Диаграмма класса блок-схемы приведена на рисунке 4.1.


Рисунок 4.2 - Диаграмма класса блок-схемы.


Для хранения всей схемы в программе присутствует класс Chart. Он хранит корневой элемент схемы (блок начала схемы), список точек вставки, объект для генерации кода программы из схемы, а так же служебные данные. Класс схемы реализует методы вставки и удаления блоков, очистки всей схемы и автоматического выравнивания блоков и точек вставки.

public class Chart

{

...ChartMainBlock root; //корневой элемент схемыCodeGenerator codeGen; //генератор кодаList<Block> blocks = new List<Block>(); //все блоки схемыList<InsertionPoint> insertionPoints = new List<InsertionPoint>();

...

}

Класс блок схемы реализует методы для автоматического выравнивания блоков и точек вставки (RealignBlocks, RegenerateInsertionPoints, GenerateInsertionPoints), методы для вставки и удаления блоков (InsertIntoBranch, CreateNewBlock, DeleteSelectedBlock, ClearChart), методы для обработки событий мыши (ProcessMouseClickInsertion, ProcessMouseClickBlockSelection, ProcessMouseMove, ProcessMouseDoubleClick), так же этот класс имеет метод для получения кода программы (GetCode).

Далее рассмотрим класс точки вставки InsertionPoint. Он приведен на рисунке 4.3.


Рисунок 4.3 - Диаграмма класса точки вставки


Далее рассмотрим класс генератора кода программы. Он приведен на рисунке 4.4.


Рисунок 4.4 - Диаграмма класса генератора кода.


Далее рассмотрим класс для выполнения кода программы. Он приведен на рисунке 4.5. Этот класс использует интерпретатор языка JavaScript Jint для платформы .NET. Для вывода результата работы программы предназначен делегат PrintCodeExecutionResultDelegate. В Jint этот делегат назначается методу print().


Рисунок 4.5 - Диаграмма класса для выполнения кода программы.


В программе используются пространство имен System.Collections.Generic, которое содержит интерфейсы и классы, определяющие универсальные коллекции, которые позволяют пользователям создавать строго типизированные коллекции, обеспечивающие повышенную производительность и безопасность типов по сравнению с не универсальными строго типизированными коллекциями.

Для списков используется List(Of T) из System.Collections.Generic. Это строго типизированный список объектов, доступных по индексу. Поддерживает методы для поиска по списку, удаления, вставки и другие операции со списками.


5. Описание интерпретатора использованного в программе


В программе был использован интерпретатор Jint.- это интерпретатор языка JavaScript для .NET приложений. Используя Jint, .NET разработчики могут добавлять динамическое поведение в свои приложения, запуская скрипты JavaScript без компиляции. Jint имеет набор возможностей которые делают возможной связь межжу окружением JavaScript и окружением .NET во время выполнения.обеспечивает весь функционал JavaScript в .NET приложениях и связь с .NET языками. Jint может использовать любые классы и объекты .NET.


5.1 Варианты использования


Ниже приведены возможные варианты использования интерпретатора Jint:

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

. Улучшение возможностей конфигурирования для изменения поведения приложения и его логики без перекомпиляции.

. Выполнение динамического кода или выражений.


5.2 Возможности Jint


Стандартные возможности JavaScript:

. объекты и методы;

. циклы (do, while, for);

. области видимости;

. условные выражения;

. JSON;

. динамические свойства;

. стандартные классы JavaScript (Math, String, Object, Number);

. регулярные выражения;

. функции;

. прототипы и конструкторы.


.3 Описание основных возможностей языка JavaScript


Ниже описанные основные возможности языка JavaScript.


5.3.1 Вывод данных

Для вывода используйте функцию print(). Эта функция принимает на вход один аргумент (строку или число) и выводит его в новой строке на форме в окне с результатом исполнения программы.


5.3.2 Переменные

Переменные в JavaScript назначаются двумя способами:

С помощью оператора «=»: переменная = значение.= 1

С помощью ключевого слова var и оператора «=»: var переменная или var переменная = значение.x; x = 1x = 1

Второй способ отличается от первого тем, что можно назначать сразу несколько переменных.x = 1, y = 2

А так же тем, что второй способ определяет значение переменной только в своем блоке кода. Если присвоить значение переменной, не объявленной с помощью инструкции var, JavaScript неявно объявит эту переменную за вас. Однако переменные, объявленные таким образом, всегда создаются как глобальные, даже если они работают только в теле функции.

В именах переменных могут использоваться латинские буквы (a...z, A...Z), цифры (0...9), знак доллара ($) и знак подчёркивания (_), при этом нельзя использовать цифру первой. Необходимо помнить, что JavaScript - регистрозависимый язык, и переменные X и x, будут считаться различными.


5.3.3 Базовые типы

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

В Javascript есть и объектные типы данных и элементарные, которые можно интерпретировать как объекты.

Элементарные - создаются простым указанием данных:orange = "Апельсин"

Объектные - например, через оператор new:

var orange = new String("Апельсин")

Кроме всем известных типов данных - в javascript есть специальное значение undefined, которое, условно говоря, обозначает что "данных нет".

Все математические функции находятся в модуле Math.

Math.floor() / Math.round() / Math.ceil() - округление.abs() - модуль числа.sin() и т.д

Строки.

Строки в javascript - полностью unicode. Кавычки двойные и одинарные работают одинаково. Длина строки хранится в свойстве length.


5.3.4 Операторы

5.3 4 1 Арифметические операторы

Арифметические операции производятся только с данными одного типа. JavaScript способен сам определять тип данных, однако не стоит уповать на него - рекомендуется самостоятельно следить за их типом. В таблице 5.1 приведены наиболее часто используемые арифметические операторы.

Существует 3 типа данных:

. строковый (string) - определяется двойными или одинарными кавычками и используется для символьных данных;

. числовой (number) - определяется отсутствием кавычек и используется для чисел (не символов);

. логический (boolean) - определяется отсутствием кавычек и используется для значений true=1 или false=0.

Также существуют специальные типы данных:

. null - отсутствие данных;

. объект (object) - программный объект (ссылка на него);

. функция (function) - определение функции.


Таблица 5.1 - Арифметические операторы

ОператорНазваниеПримерРезультат+Сложениеx + yСложение двух чисел или склеивание двух строк-Вычитаниеx - yВычитание y из x или удаление строки y из строки х*Умножениеx * yПеремножение двух чисел/Делениеx / yДеление числа x на число y %Деление по модулю (остаток)x % yОстаток от деления числа x на число y++Инкремент (увеличение на 1)x++Эквивалентно x+1

Примеры использования:

+ 3 // результат 9

- 3 // результат 3

* 3 // результат 18

/ 3 // результат 2

% 3 // результат 2

++ // результат 7

-- // результат 5

Можно использовать и с переменными:= 3 // значение x - 3= 5 // значение y - 5= x + y // значение z - 8

Возможно использование в выражениях со скобками:

+ 5 * 2 // результат 14

(4 + 5) * 2 // результат 18

В арифметических операциях логические значения считаются: true - 1, false - 0:

+ true // результат 6

+ false // результат 5

* true // результат 4

* false // результат 0+ true // результат 2+ false // результат 1

Оператор сложения можно использовать для склейки строк:

"Java" + "Script" // результат "JavaScript"= "Java"= "Script"+ b // результат "JavaScript"

"Уровень" + 5 // результат "Уровень5"

"Уровень" + true // результат "Уровеньtrue"

"1" + "2" // результат "12"

Другие арифметические операторы со строками дают значение NaN:

"J" * 5 // результат NaN

"J" - 5 // результат NaN

"J" - "J" // результат NaN

. 3. 4. 2 Побитовые операторы

& - and

| - or

^ - xor

>>, >>>, << - побитовые сдвиги

Все побитовые операции работают с 4-байтовым signed int.

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

Для отрицательных чисел - все по-другому. Например, -9 в битовом виде выглядит как: 11111111111111111111111111110111.

Операция >>> даст эффект: -9 >>> 2 будет в битовом виде 00111111111111111111111111111101, то есть 1073741821.

. 3. 4 .3 Сравнение

==, !=, <, >, <=, >=, ===, !==

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

"B">"a"

"bc" < "bd"

Сравнение == делается с приведением типов, а === без приведения типов, например:

== false // верно

// но

!== false //типы разные


5.3.5 Массивы

Javascript поддерживает два вида структуры "массив":

. Ассоциативный массив (хеш), где данные хранятся по произвольному ключу.

. Числовой массив Array, где данные хранятся по номерам.

Javascript - очень гибкий язык, поэтому технически в Array можно хранить произвольные ключи, как в Object. Но лучше использовать типы по назначению.

Для хранения данных по номеру предназначен тип Array.


var arr = new Array().test = 5[1] = "new"

В типе Array есть специальные методы, ориентированные именно на работу с числовыми ключами.

. 3. 5. 1 Создание и изменение

Есть два эквивалентных способа создания массива:

var a = new Array()a = []

Или сразу со значениямиa = new Array("a", 1, true)a = ["a", 1, true]

Эти способы работают одинаково, кроме объявления вида new Array(10), когда у конструктора есть единственный аргумент-число.

Такое объявление создаст пустой массив (все элементы undefined) длиной 10. По возможности, не используйте new Array.

Отсчет элементов начинается с нуля:

alert(a[0]) // => "a"

Массив хранит данные по численным ключам, но внутри он использует точно такой же хэш (ту же структуру данных), как и обычный объект, поэтому можно сделать так:

var a = []

a[1] = 1

a[999999] = 2

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

. 3. 5. 2 Перебор элементов

Перебор элементов обычно (когда индексы непрерывные) осуществляется простым циклом:

var arr = [ "array", "elements", "here" ](var i=0; i<arr.length; i++) {

... сделать что-то с arr[i] ...

}

Если индексы - с разрывами, то перебор осуществляется так же, как в объектах:

var arr = [][1] = 123[9999] = 456(var i in arr) {(!arr.hasOwnProperty(i)) continue;

... сделать что-то с arr[i] ...

}


5.3.6 Функции

5. 3. 6. 1 Создание функций

Существует два способа создать функцию. Основное отличие в результате их работы - в том, что именованная функция видна везде, а анонимная - только после объявления. Способы создания функций представлены в в таблице 5.2.


Таблица 5.2-Способы задания функций

Именованные (FunctionDeclaration)Анонимные (FunctionExpression)function имя(параметры) { ... }var имя = function(параметры) {…} ... var имя = new Function(параметры, '...')Именованные функции доступны везде в области видимостиАнонимные - доступны только с момента объявления. Синтаксис new Function используется редко, в основном для получения функции из текста, например, динамически загруженного с сервера в процессе выполнения скриптов./* функция sum определена ниже */ var a = sum(2,2) function sum(x,y) { return x+y }/* будет ошибка, т.к sum еще не существует */ var a = sum(2,2) var sum = function(x,y) { return x+y }

. 3 .5. 2 Функции - объекты

В javascript функции являются полноценными объектами встроенного класса Function. Именно поэтому их можно присваивать переменным, передавать и, конечно, у них есть свойства:

function f() {...}.test = 6

...(f.test) // 6

Свойства функции доступны и внутри функции, так что их можно использовать как статические переменные.

function func() {funcObj = arguments.callee.test++(funcObj.test)

}

func.test = 1

func()

func()

В начале работы каждая функция создает внутри себя переменную arguments и присваивает arguments.callee ссылку на себя. Так что arguments.callee.test - свойство func.test, т.е статическая переменная test.

. 3. 5. 3 Параметры функции

Функции можно запускать с любым числом параметров.

Если функции передано меньше параметров, чем есть в определении, то отсутствующие считаются undefined.

Непосредственно перед входом в тело функции, автоматически создается объект arguments, который содержит:

. аргументы вызова, начиная от нуля;

. длину в свойстве length;

. ссылку на саму функцию в свойстве callee;

. свойство arguments похоже на массив, т.к у него есть длина и числовые индексы.


6. Описание системы и руководство пользователя


Нами было создано приложение программа-редактор схем. С помощью этой программы можно создавать, сохранять, редактировать блок-схему программы, а также выполнять исходный код, который генерируется по ходу редактирования схемы. Главное окно приложения показано на рисунке 6.1.


Рисунок 6.1 - Внешний вид главной формы приложения


На главной форме приложения расположены следующие компоненты, определяющие функциональность программы:

. главное меню;

. панель инструментов и операций;

. окно с исходным кодом программы, соответствующей построенной схеме;

. окно с результатом выполнения программы.


6.1 Описание главного меню


Главное меню программы имеет два раздела «Файл» и «Код» программы.

Раздел «Файл» представлен на рисунке 6.2.


Рисунок 6.2 - раздел «Файл» главного меню программы


Описание опций раздела «Файл» главного меню программы:

. Новая схема - создать новую схему.

. Открыть - открыть существующую схему из формата XML.

. Сохранить - сохранить блок-схему в уже открытый файл (если файл был открыт) иначе сохранить в новый файл.

. Сохранить как - сохранить схему в новый файл.

. Выход - выйти из программы.

Раздел «Код программы» представлен на рисунке 6.3.

Рисунок 6.3 - раздел «Код программы» главного меню программы

Выполнить - запустить выполнение кода программы. Результат выполнения будет отображен в окне Результат выполнения кода.


6.2 Описание панели инструментов и операций


Ниже приведено описание панели инструментов и операций, которые используются в программе:

. Кнопка «Обычный блок» позволяет добавить в схему блок процесса.

. Кнопка «Условие» позволяет добавить в схему блоки условия.

. Кнопка «Цикл» позволяет добавить в схему блоки цикла.

. Кнопка «Очистить схему» удаляет всю структуру схемы и возвращает схему к исходному состоянию begin-end.

. Кнопка «Удалить блок» позволяет удалить выделенный блок или всю ветку, чтобы выбрать блок надо кликнуть по нему.


6.3 Описание вставки новых блоков


Для вставки нового блока нужно:

. на панели инструментов нажать кнопку нужного блока;

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


Рисунок 6.4 - Режим вставки нового блока


3. Кликнуть по нужной точке вставки. Вставится новый блок и программа сама выровняет все блоки схемы (рисунок 6.5):


Рисунок 6.5 - Результат вставки нового блока


6.4 Выполнение кода блок схемы


По ходу редактирования блок схемы, в правой части окна будет обновляться код схемы. В любой момент его можно выполнить, воспользовавшись кнопкой «Выполнить» из раздела «Код программы» в главном меню.

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


7. Примеры программ созданных в редакторе


В этом разделе приведены программы, созданные в редакторе.


7.1 Решение квадратного уравнения


Пример решения квадратного уравнения приведен на рисунке 7.1.

Рисунок 7.1 - Решение квадратного уравнения


7.2 Сортировка массива пузырьком


Пример сортировки массива приведен на рисунке 7.2.

Рисунок 7.2 - Сортировка массива пузырьком


.3 Среднее значение элементов массива


Пример вычисления среднего значения элементов массива приведен на рисунке 7.3.


Рисунок 7.3 - Среднее значение элементов массива


Заключение


В ходе данной курсовой работы была разработана система визуального программирования. Были реализованы основные функции этой системы, такие как сохранение построенной схемы в XML, автоматическая генерация программного кода и автоматическое расположение блоков на форме.

Был разработал удобный визуальный редактор для создания блок-схем программ. С его помощью пользователь может в интерактивном режиме проверять результат своей работы, запускать выполнение кода своей программы.

Программа была написана на платформе .NET Framework, были изучены и использованы некоторые возможности этой платформы.

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


Приложение А


(справочное)

Исходный текст программы редактора схем

1) Block.csSystem;System.Collections.Generic;System.Drawing;flowchart.blocks;System.Xml.Serialization;flowchart

{

[Serializable]abstract class Block

{List<Block> Items;

[XmlIgnore]Block Branch;int w = 100;int h = 50;int marginTop;int marginRight;int marginBottom;int marginLeft;

[XmlIgnore]int width;

[XmlIgnore]int height;

[XmlIgnore]int X;

[XmlIgnore]int Y;

[XmlIgnore]bool isSelected = false;

//смещение вниз чтобы не перекрывало точку вставки

protected int dy = 18;

[XmlAttribute]string Text;

[XmlAttribute]string TextAtTheEnd;Font drawFont = new Font("Sans Serif", 10);SolidBrush drawBrush = new SolidBrush(Color.Black);static StringFormat strFormat = new StringFormat()

{= StringAlignment.Center,= StringAlignment.Center

};Block() { }Block (string text)

{= null;= new List<Block>();= 0;= 0;.Text = text;

}virtual bool PointInsideBlock(int x, int y)

{blockX = X + width / 2 - w/2;blockY = Y + dy;((x > blockX && x < blockX + w) && (y > blockY && y < blockY + h));

}void AdjustSize()

{clientWidth = 0;clientHeight = 0;(this is Branch)

{(Block item in Items)

{.AdjustSize();(clientWidth < item.width)= item.width;+= item.height;

}minWidth = 180;minHeight = 16;(clientHeight < minHeight)= minHeight;(clientWidth < minWidth)= minWidth;= clientHeight;= clientWidth;

}

{(Block item in Items)

{.AdjustSize();(clientHeight < item.height)= item.height;+= item.width;

}= 40;= 40;= 10;= 10;(this is ChartMainBlock)

{= 40;= 18;

}if (this is RegularBLock)

{= 16;= 10;= 120;= 60;

}if (this is ConditionBlock)

{= 92;= 16;

}if (this is LoopBlock)

{= 80;= 80;

}= marginLeft + clientWidth + marginRight;= marginTop + clientHeight + marginBottom;

}

}void AdjustPosition(int ox, int oy)

{= ox;= oy;(this is Branch)

{cy = Y;(Block item in Items)

{.AdjustPosition(ox + (width - item.width) / 2, cy);+= item.height;

}

}

{cx = X + marginLeft;(Block item in Items)

{.AdjustPosition(cx, Y + marginTop);

cx += item.width;

}

}

}

/// <summary>

/// Если открыть блок из файла, то информация о том какой ветке принадлежит каждый блок теряется

/// Метод устанавливает для каждого блока какой ветке он принадлежит

/// </summary>void SetBranches(Block branch)

{.Branch = branch;(this is RegularBLock);(Block block in Items)

{.SetBranches(this);

}

}abstract void Draw(Graphics g);

}

}

) RegularBlock.csSystem;System.Drawing;System.Drawing.Drawing2D;flowchart.blocks

{

[Serializable]class RegularBLock : Block

{RegularBLock() { }RegularBLock(string text) : base(text) { }override void Draw(Graphics g)

{containerCenter = X + width / 2;pen = isSelected ? new Pen(Color.Firebrick, 3) : new Pen(Color.Black, 1);.EndCap = LineCap.ArrowAnchor;.DrawLine(pen, containerCenter, Y, containerCenter, Y + dy);.EndCap = LineCap.NoAnchor;.DrawRectangle(pen, containerCenter - w/2, Y + dy, w, h);r = new Rectangle(containerCenter - w / 2, Y + dy, w, h);.DrawString(Text, drawFont, drawBrush, r, strFormat);.DrawLine(pen, containerCenter, Y + height - dy, containerCenter, Y + height);

}

}

}


) Branch.csSystem;System.Drawing;flowchart.blocks

{

[Serializable]class Branch : Block

{Branch() { }Branch(string text): base(text) { }override void Draw(Graphics g)

{pen = isSelected ? new Pen(Color.Firebrick, 3) : new Pen(Color.Black, 1);containerCenter = X + width / 2;.DrawLine(pen, containerCenter, Y, containerCenter, Y + dy);;

}

}

}

) ChartMainBlock.csSystem;System.Collections.Generic;System.Drawing;System.Drawing.Drawing2D;System.IO;System.Xml.Serialization;flowchart.blocks

{

[Serializable]class ChartMainBlock : Block

{ChartMainBlock() { }ChartMainBlock(string text) : base(text) { }override bool PointInsideBlock(int x, int y)

{blockX = X + width / 2 - w / 2;blockY = Y - dy;((x > blockX && x < blockX + w) && (y > blockY && y < blockY + h));

}override void Draw(Graphics g)

{

//центр контейнераcontainerCenter = X + width / 2;

//центр контейнера минус половина ширины блока

int dx = X + width/2 - w/2;pen = isSelected ? new Pen(Color.Firebrick, 3) : new Pen(Color.Black, 1);.DrawLine(pen, dx + h / 2, Y - dy, dx + w - h / 2, Y - dy);.DrawLine(pen, dx + h / 2, Y + h - dy, dx + w - h / 2, Y + h - dy);.DrawArc(pen, dx, Y - dy, h, h, 90, 180);.DrawArc(pen, dx + w - h, Y - dy, h, h, 270, 180);.DrawLine(pen, containerCenter, Y + h - dy, containerCenter, Y + h);r = new Rectangle(dx, Y - dy, w, h);.DrawString("begin", drawFont, drawBrush, r, strFormat);

//блок в конце схемыdowny = Y + height;.DrawLine(pen, dx + h / 2, downy, dx + w - h / 2, downy);.DrawLine(pen, dx + h / 2, downy + h, dx + w - h / 2, downy + h);.DrawArc(pen, dx, downy, h, h, 90, 180);.DrawArc(pen, dx + w - h, downy, h, h, 270, 180);= new Rectangle(dx, downy, w, h);.DrawString("end", drawFont, drawBrush, r, strFormat);.EndCap = LineCap.ArrowAnchor;.DrawLine(pen, containerCenter, Y + height - dy, containerCenter, Y + height);.EndCap = LineCap.NoAnchor;

}void SaveToXml(string path)

{fStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);xmlFormat = new XmlSerializer((ChartMainBlock),Type[]

{(Block),(ConditionBlock),(RegularBLock),(Branch),(LoopBlock),(ChartMainBlock),(List<Block>),(List<ConditionBlock>),(List<RegularBLock>),(List<Branch>),(List<LoopBlock>),(List<ChartMainBlock>),

}

);.Serialize(fStream, this);.Close();

}

}

}

) ConditionBLock.csSystem;System.Drawing;System.Drawing.Drawing2D;flowchart.blocks

{

[Serializable]class ConditionBlock : Block

{ConditionBlock() { }ConditionBlock(string text) : base(text) { }override void Draw(Graphics g)

{

//центр контейнераcontainerCenter = X + width / 2;

//центр контейнера минус половина ширины блока

int dx = containerCenter - w / 2;pen = isSelected ? new Pen(Color.Firebrick, 3) : new Pen(Color.Black, 1);

//верхняя линия.EndCap = LineCap.ArrowAnchor;.DrawLine(pen, containerCenter, Y, containerCenter, Y + dy);.EndCap = LineCap.NoAnchor;

//сам блок в виде ромба[] points = new Point[]

{Point(dx + w / 2, Y + dy),Point(dx + w, Y + h / 2 + dy),Point(dx + w / 2, Y + h + dy),Point(dx, Y + h / 2 + dy),Point(dx + w / 2, Y + dy),

};.DrawCurve(pen, points, 0);r = new Rectangle(dx, Y + dy, w, h);.DrawString(Text, drawFont, drawBrush, r, strFormat);

//подпись да= new Rectangle(dx - w/2, Y + dy, w/2, h/2);.DrawString("да", drawFont, drawBrush, r, strFormat);

//подпись нет= new Rectangle(dx + w , Y + dy, w / 2, h / 2);.DrawString("нет", drawFont, drawBrush, r, strFormat);left = Items[0];right = Items[1];

//левая линия= new Point[]

{Point(containerCenter - w / 2, Y + dy + h/2),Point(left.X + left.width/2, Y + dy + h/2),Point(left.X + left.width/2, left.Y),

};.DrawCurve(pen, points, 0);

//правая линия= new Point[]

{Point(containerCenter + w/2, Y + dy + h/2),Point(right.X + right.width/2, Y + dy + h/2),Point(right.X + right.width/2, right.Y),

};.DrawCurve(pen, points, 0);

//нижняя часть= new Point[]

{Point(left.X + left.width/2, left.Y + left.height),Point(left.X + left.width/2, Y + height - 20),Point(right.X + right.width/2, Y + height - 20),Point(right.X + right.width/2, right.Y + right.height),

};.DrawCurve(pen, points, 0);.DrawLine(pen, containerCenter, Y + height - 20, containerCenter, Y + height);

}

}

}

) LoopBlock.csSystem;System.Drawing;System.Drawing.Drawing2D;flowchart.blocks

{

[Serializable]class LoopBlock : Block

{LoopBlock() { }LoopBlock(string text) : base(text) { }override void Draw(Graphics g)

{containerCenter = X + width / 2;dx = containerCenter - w / 2;pen = isSelected ? new Pen(Color.Firebrick, 3) : new Pen(Color.Black, 1);.EndCap = LineCap.ArrowAnchor;.DrawLine(pen, containerCenter, Y, containerCenter, Y + dy);.EndCap = LineCap.NoAnchor;

//начало цикла[] points = new Point[]

{Point(dx + h / 3, Y + dy),Point(dx + w - h/3, Y + dy),Point(dx + w, Y + dy + h/3),Point(dx + w, Y + h + dy),Point(dx , Y + h + dy),Point(dx, Y + dy + h/3),Point(dx + h / 3, Y + dy),

};.DrawCurve(pen, points, 0);.DrawLine(pen, containerCenter, Y + h + dy*2, containerCenter, Y + h + dy);r = new Rectangle(containerCenter - w / 2, Y + dy, w, h);.DrawString(Text, drawFont, drawBrush, r, strFormat);

//смещение к низу контейнераdelta = height - h - 35;

pen.EndCap = LineCap.ArrowAnchor;.DrawLine(pen, containerCenter, Y + delta, containerCenter, Y + dy + delta);.EndCap = LineCap.NoAnchor;

//конец цикла= new Point[]

{Point(dx, Y + dy + delta),Point(dx + w, Y + dy+ delta),Point(dx + w, Y + dy + h - h/3+ delta),Point(dx + w - h/3, Y + h + dy+ delta),Point(dx + h/3, Y + h + dy+ delta),Point(dx, Y + dy + h - h/3+ delta),Point(dx, Y + dy + delta),

};.DrawCurve(pen, points, 0);= new Rectangle(containerCenter - w / 2, Y + dy + delta, w, h);.DrawString(TextAtTheEnd, drawFont, drawBrush, r, strFormat);.DrawLine(pen, containerCenter, Y + h + dy + delta, containerCenter, Y + h + dy*2 + delta);

}

}

}

) MainForm.csSystem;System.Collections.Generic;System.IO;System.Windows.Forms;System.Xml.Serialization;Jint;flowchart.blocks;flowchart

{partial class MainForm : Form

{WorkAreaForm workAreaForm;saveFileDialog = new SaveFileDialog { Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*" };openFileDialog = new OpenFileDialog { Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*" };string filePath = String.Empty;MainForm()

{();= new WorkAreaForm(codeTextBox);.MdiParent = this;.Clear();.Show();.Chart = new Chart();.DrawChart();.Text = workAreaForm.Chart.GetCode();.Height = ClientSize.Height;.Left = 0;.Top = menuStrip1.Height + 1;.Height = ClientSize.Height - menuStrip1.Height;.Left = ClientSize.Width - codePanel.Width;.Top = menuStrip1.Height + 1;.Left = 0;.Width = codePanel.Width;.Height = codePanel.Height- 200;.Height = 130;.Width = codePanel.Width;.Left = 0;.Top = codePanel.Top + codeTextBox.Height + 40;.Top = codeResultTextBox.Top - 25;

}void button1_Click(object sender, EventArgs e)

{.Insertion = true;.BlockType = 1;.UpdateChart(true);

}void button2_Click(object sender, EventArgs e)

{.Insertion = true;.BlockType = 2;.UpdateChart(true);

}void loopButton_Click(object sender, EventArgs e)

{.Insertion = true;.BlockType = 3;.UpdateChart(true);

}void deleteButton_Click(object sender, EventArgs e)

{.DeleteBLock();

}void MainForm_Resize(object sender, EventArgs e)

{.Height = ClientSize.Height - menuStrip1.Height;.Height = ClientSize.Height - menuStrip1.Height;.Left = ClientSize.Width - codePanel.Width;.Height = codePanel.Height - 200;.Top = codePanel.Top + codeTextBox.Height + 40;.Top = codeResultTextBox.Top - 25;

}void button3_Click(object sender, EventArgs e)

{.ClearChart();

}void saveToolStripMenuItem_Click(object sender, EventArgs e)

{(filePath != String.Empty)

{.Chart.root.SaveToXml(filePath);;

}fileName = String.Empty;(saveFileDialog.ShowDialog() == DialogResult.OK)= saveFileDialog.FileName;(fileName == String.Empty);.Chart.root.SaveToXml(fileName);= fileName;.Text = fileName;

}void saveAsToolStripMenuItem_Click(object sender, EventArgs e)

{fileName = String.Empty;(saveFileDialog.ShowDialog() == DialogResult.OK)= saveFileDialog.FileName;(fileName == String.Empty);.Chart.root.SaveToXml(fileName);= fileName;.Text = fileName;

}void exitToolStripMenuItem_Click(object sender, EventArgs e)

{();

}void openToolStripMenuItem_Click(object sender, EventArgs e)

{fileName = String.Empty;(openFileDialog.ShowDialog() == DialogResult.OK)= openFileDialog.FileName;(fileName == String.Empty);fStream = File.OpenRead(fileName);xmlFormat = new XmlSerializer((ChartMainBlock),Type[]

{(Block),(ConditionBlock),(RegularBLock),(Branch),(LoopBlock),(ChartMainBlock),(List<Block>),(List<ConditionBlock>),(List<RegularBLock>),(List<Branch>),(List<LoopBlock>),(List<ChartMainBlock>),

}

);rootBlockFromFile;

{= (ChartMainBlock)xmlFormat.Deserialize(fStream);

}(System.Exception ex)

{.Show(ex.Message, "Ошибка при попытке открыть файл");.Close();;

}.Close();= fileName;.Text = filePath;.Items[0].SetBranches(rootBlockFromFile);.Chart.root = rootBlockFromFile;.Chart.codeGen = new CodeGenerator(rootBlockFromFile);.Chart.RealignBlocks();.Chart.RegenerateInsertionPoints();.Chart.UpdateAllBlocksList();.UpdateChart();.UpdateCode();

}void newChartToolStripMenuItem_Click(object sender, EventArgs e)

{.ClearChart();= String.Empty;.Text = "Новая схема";

}void executeToolStripMenuItem_Click(object sender, EventArgs e)

{script = @codeTextBox.Text;engine = new JsCodeInterpreter(codeResultTextBox);

{.RunScript(script);

}(JintException ex)

{.Show(ex.Message, "Ошибка при выполнении программы");

}

}

}

}

) WorkAreaForm.csSystem.Drawing;System.Drawing.Drawing2D;System.Windows.Forms;flowchart.blocks;flowchart

{partial class WorkAreaForm : Form

{Bitmap _picture;Graphics g;TextBox codeTextBox;Chart Chart;BlockProreptiesEditor blockProreptiesEditorForm;bool Insertion = false;int BlockType = 0;WorkAreaForm(TextBox textBox)

{= textBox;();.Width = ClientSize.Width;.Height = ClientSize.Height;.Top = panel1.Left = 0;

_picture = new Bitmap(ClientSize.Width, ClientSize.Height);.Image = _picture;.Width = ClientSize.Width;.Height = ClientSize.Height;.Top = workAreaFormPictureBox.Left = 0;= Graphics.FromImage(workAreaFormPictureBox.Image);.SmoothingMode = SmoothingMode.AntiAlias;

}void WorkAreaForm_Load(object sender, System.EventArgs e)

{= new Point(95, 0);

}void workAreaFormPictureBox_MouseClick(object sender, MouseEventArgs e)

{(e.Button == MouseButtons.Right)

{= false;();= 0;= Cursors.Arrow;;

}(Insertion)

{.ProcessMouseClickInsertion(e.X, e.Y, BlockType);();= false;= 0;.Text = Chart.GetCode();= Cursors.Arrow;

}

{.ProcessMouseClickBlockSelection(e.X, e.Y);();

}

}void UpdateChart(bool insertion = false)

{(Chart.width > ClientSize.Width)

{.Width = Chart.width;

_picture = new Bitmap(Chart.width, ClientSize.Height);.Image = _picture;= Graphics.FromImage(workAreaFormPictureBox.Image);.SmoothingMode = SmoothingMode.AntiAlias;

}if (Chart.height > ClientSize.Height)

{.Height = Chart.height;

_picture = new Bitmap(ClientSize.Width, Chart.height);.Image = _picture;= Graphics.FromImage(workAreaFormPictureBox.Image);.SmoothingMode = SmoothingMode.AntiAlias;

}();(insertion);

}void UpdateCode()

{.Text = Chart.GetCode();

}void DrawChart(bool insertion = false)

{.Draw(g, insertion);.Refresh();

}void Clear()

{.Clear(Color.White);

}void WorkAreaForm_Resize(object sender, System.EventArgs e)

{.Width = ClientSize.Width;.Height = ClientSize.Height;(workAreaFormPictureBox.Width < panel1.Width || workAreaFormPictureBox.Height < panel1.Height)

{.Width = panel1.Width;.Height = panel1.Height;

_picture = new Bitmap(panel1.Width, panel1.Height);.Image = _picture;= Graphics.FromImage(workAreaFormPictureBox.Image);.SmoothingMode = SmoothingMode.AntiAlias;();

}

}void workAreaFormPictureBox_MouseMove(object sender, MouseEventArgs e)

{(!Insertion);movementResult = Chart.ProcessMouseMove(e.X, e.Y);= movementResult ? Cursors.Hand : Cursors.Arrow;(true);

}void workAreaFormPictureBox_MouseDoubleClick(object sender, MouseEventArgs e)

{block = Chart.ProcessMouseDoubleClick(e.X, e.Y);(block == null);(block is RegularBLock)

{= new BlockProreptiesEditor("regular", block, this);

}if (block is ConditionBlock)

{= new BlockProreptiesEditor("condition", block, this);

}if (block is LoopBlock)

{= new BlockProreptiesEditor("loop_for", block, this);

}.MdiParent = this.MdiParent;.Show();

}void DeleteBLock()

{(Chart.DeleteSelectedBlock())

{();();

}

}void ClearChart()

{.ClearChart();();();

}

}

}

) BlockProreptiesEditor.csSystem;System.Drawing;System.Windows.Forms;flowchart

{partial class BlockProreptiesEditor : Form

{Block blockToEdit;WorkAreaForm workAreaForm;string loopType;BlockProreptiesEditor(string type, Block block, WorkAreaForm workAreaForm)

{= type;();.blockToEdit = block;.workAreaForm = workAreaForm;.Text = block.Text;(type)

{"regular":.Text = "Текст";= "Обычный блок";();;"condition":.Text = "Условие";= "Условие";();;"loop_for":.Text = " Цикл";= "Цикл";.SelectedIndex = 0;;"loop_while":.Text = "Предусловие";= "Цикл";.SelectedIndex = 1;;"loop_do_while":.Text = "Постусловие";= "Цикл";.SelectedIndex = 2;;

}

}void AdjustFormFormForConditionOrRegular()

{.Visible = false;.Visible = false;= 300;= 170;.Top = 15;.Left = 1;.Top = 12;.Left = 55;.Height = 80;

}void loopTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)

{(loopTypeComboBox.SelectedIndex)

{0:.Text = " Цикл";= "loop_for";;1:.Text = "Предусловие";= "loop_while";;2:.Text = "Постусловие";= "loop_do_while";;

}

}void cancelButton_Click(object sender, EventArgs e)

{();

}void okButton_Click(object sender, EventArgs e)

{(loopType == "loop_do_while")

{.Text = "do";.TextAtTheEnd = blockContentTextBox.Text;

}

{.Text = blockContentTextBox.Text;.TextAtTheEnd = "";

}(Block block in workAreaForm.Chart.blocks)

{.isSelected = false;

}.UpdateChart();.UpdateCode();();

}void BlockProreptiesEditor_Load(object sender, EventArgs e)

{= new Point(400, 150);

}

}

}

) Chart.csSystem;System.Collections.Generic;System.Drawing;flowchart.blocks;System.Xml.Serialization;flowchart

{

[Serializable]class Chart

{ChartMainBlock root;Block selectedBlock;

[XmlIgnore]CodeGenerator codeGen;

[XmlIgnore]List<Block> blocks = new List<Block>();

[XmlIgnore]List<InsertionPoint> insertionPoints = new List<InsertionPoint>();

[XmlIgnore]int height;

[XmlIgnore]int width;Chart()

{= new ChartMainBlock("main block");rootMainBranch = new Branch("main branch");.Items.Add(rootMainBranch);.Add(root);.Add(rootMainBranch);();();= new CodeGenerator(root);

}void RealignBlocks()

{.AdjustSize();.AdjustPosition(0, 20);= root.width;= root.height+100;

}void RegenerateInsertionPoints()

{.Clear();(root);

}void GenerateInsertionPoints(Block block)

{(block is Branch)

{x = block.X + block.width / 2;(int i = 0; i < block.Items.Count; i++)

{y = block.Items[i].Y;point = new InsertionPoint();.branch = block;.x = x;.y = y;.index = i;.Add(point);(block.Items[i]);

}p = new InsertionPoint();.branch = block;(block.Items.Count == 0)

{.x = x;.y = block.Y + block.height / 2;

}

{.x = x;.y = block.Y + block.height;

}.index = block.Items.Count;.Add(p);

}

{(Block item in block.Items)

{(item);

}

}

}void InsertIntoBranch(Block branch, Block newBlock, int index)

{.Branch = branch;.Items.Insert(index, newBlock);();();

}Block CreateNewBlock(int type)

{(type)

{(1):regularBLock = new RegularBLock("action");.Add(regularBLock);regularBLock;(2):conditionBlock = new ConditionBlock("condition");left = new Branch("condition left branch");right = new Branch("condition right branch");

//left.Branch = right.Branch = conditionBlock;.Items.Add(left);.Items.Add(right);.Add(conditionBlock);.Add(left);.Add(right);conditionBlock;(3):loopBlock = new LoopBlock("loop");.TextAtTheEnd = "loop end";loopBranch = new Branch("loop branch");

//loopBranch.Branch = loopBlock;.Items.Add(loopBranch);.Add(loopBlock);.Add(loopBranch);loopBlock;:null;

}

}

/// <summary>

/// Проверить является ли расстояние между двумя точками меньше заданного

/// </summary>bool CheckTwoPoints(int x1, int y1, int x2, int y2, int r)

{dx = Math.Abs(x1 - x2);dy = Math.Abs(y1 - y2);dx * dx + dy * dy <= r * r;

}InsertionPoint GetPointAt(int x, int y)

{(InsertionPoint ip in insertionPoints)

{(CheckTwoPoints(ip.x, ip.y, x, y, ip.R))

{ip;

}

}null;

}

/// <summary>

/// Удаляет выбранный блок схемы

/// </summary>

/// <returns>true - если был удален блок (было что удалять) </returns>

public bool DeleteSelectedBlock()

{(selectedBlock == null)false;.Branch.Items.Remove(selectedBlock);();();();true;

}void UpdateAllBlocksList()

{.Clear();(root);

}void WalkChart(Block block)

{.Add(block);(var item in block.Items)

{(item);

}

}void ClearChart()

{.Items[0].Items.Clear();.Clear();();();

}

#region mouse events handling

void ProcessMouseClickInsertion(int mouseX, int mouseY, int blockType)

{insertionPointClicked = GetPointAt(mouseX, mouseY);(insertionPointClicked == null);newBLock = CreateNewBlock(blockType);(insertionPointClicked.branch, newBLock, insertionPointClicked.index);

}void ProcessMouseClickBlockSelection(int mouseX, int mouseY)

{= null;(Block block in blocks)

{.isSelected = false;

}(Block block in blocks)

{(block is Branch || block is ChartMainBlock);(block.PointInsideBlock(mouseX, mouseY))

{= block;(block);;

}

}

}bool ProcessMouseMove(int mouseX, int mouseY)

{result = false;(InsertionPoint ip in insertionPoints)

{(CheckTwoPoints(ip.x, ip.y, mouseX, mouseY, ip.R))

{.underCursor = true;= true;

}

{.underCursor = false;

}

}result;

}Block ProcessMouseDoubleClick(int mouseX, int mouseY)

{(Block block in blocks)

{(block is Branch || block is ChartMainBlock);(block.PointInsideBlock(mouseX, mouseY))

{block;

}

}null;

}

#endregionvoid selectBlock(Block block)

{.isSelected = true;(block is RegularBLock);(Block item in block.Items)

{(item);

}

}

//отрисовка схемыvoid Draw(Graphics g, bool insertion = false)

{.Draw(g);(root, g);(!insertion) return;(InsertionPoint insertionPoint in insertionPoints)

{.draw(g);

}

}void drawBlockItems(Block block, Graphics g)

{(Block item in block.Items)

{.Draw(g);(item, g);

}

}string GetCode()

{codeGen.GetGeneratedCode();

}

}

}

) CodeGenerator.csSystem;flowchart.blocks;flowchart

{class CodeGenerator

{Block root;string code;

//новая строкаstring br = Environment.NewLine;int tab = 2;CodeGenerator(Block root)

{.root = root;

}string GetGeneratedCode()

{= "";(root, 0);code;

}void GenerateCode(Block block, int indent)

{(block is ChartMainBlock)

{(block.Items[0], indent);

}if (block is Branch)

{(var item in block.Items)

{(item, indent);

}

}if (block is RegularBLock)

{+= GetIndent(indent);+= block.Text + ";" + br;

}if (block is ConditionBlock)

{+= GetIndent(indent) + String.Format("if ({0})", block.Text) + br;+= GetIndent(indent) + "{" + br;(block.Items[0], indent + tab);+= GetIndent(indent) + "}" + br;+= GetIndent(indent) + "else" + br;+= GetIndent(indent) + "{" + br;(block.Items[1], indent + tab);+= GetIndent(indent) + "}" + br;

}if (block is LoopBlock)

{+= GetIndent(indent) + block.Text + br;+= GetIndent(indent) + "{" + br;(block.Items[0], indent + tab);+= GetIndent(indent) + "} ";(block.TextAtTheEnd != "")

{+= block.TextAtTheEnd + ";";

}+= br;

}

}string GetIndent(int indent)

{res = "";(int i = 0; i < indent; i++)

{+= " ";

}res;

}

}

}

) InsertionPoint.csSystem.Drawing;flowchart

{class InsertionPoint

{Block branch;int index;int x;int y;bool underCursor = false;int R = 10;int paintingR = 4;void draw(Graphics g)

{.FillEllipse(Brushes.Firebrick, x - paintingR, y - paintingR, 2 * paintingR, 2 * paintingR);(underCursor)

{.FillEllipse(Brushes.CornflowerBlue, x - R, y - R, 2 * R, 2 * R);

}

}

}

}

) JsCodeInterpreter.csSystem;System.Windows.Forms;Jint;flowchart

{class JsCodeInterpreter

{TextBox textBox;JintEngine jsEngine;JsCodeInterpreter(TextBox textBox)

{.textBox = textBox;= new JintEngine();print = delegate(object text) { textBox.Text += text + Environment.NewLine; };.SetFunction("print", print);

}delegate void PrintCodeExecutionResultDelegate(object text);void RunScript(string script)

{.Text = "";.Run(script);

}

}

Приложение Б.

(справочное)

XML файл генерируемый программой


<?xml version="1.0"?>

<ChartMainBlock xmlns:xsi="#"justify"><Items>

<Block xsi:type="Branch" Text="main branch">

<Items>

<Block xsi:type="RegularBLock" Text="a = 1" TextAtTheEnd="">

<Items />

</Block>

<Block xsi:type="RegularBLock" Text="b = 2" TextAtTheEnd="">

<Items />

</Block>

<Block xsi:type="RegularBLock" Text="c = -3" TextAtTheEnd="">

<Items />

</Block>

<Block xsi:type="RegularBLock" Text="d = b*b - 4*a*c" TextAtTheEnd="">

<Items />

</Block>

<Block xsi:type="ConditionBlock" Text="d &gt;= 0" TextAtTheEnd="">

<Items>

<Block xsi:type="Branch" Text="condition left branch">

<Items>

<Block xsi:type="RegularBLock" Text="x1 = (-b - Math.sqrt(d))/2*a" TextAtTheEnd="">

<Items />

</Block>

<Block xsi:type="RegularBLock" Text="x1 = (-b + Math.sqrt(d))/2*a" TextAtTheEnd="">

<Items />

</Block>

<Block xsi:type="RegularBLock" Text="print('x1=' + x1)" TextAtTheEnd="">

<Items />

</Block>

<Block xsi:type="RegularBLock" Text="print('x2=' + x2)" TextAtTheEnd="">

<Items />

</Block>

</Items>

</Block>

<Block xsi:type="Branch" Text="condition right branch">

<Items>

<Block xsi:type="RegularBLock" Text="print('корней нет')" TextAtTheEnd="">

<Items />

</Block>

</Items>

</Block>

</Items>

</Block>

</Items>

</Block>

</Items>

</ChartMainBlock>

Список литературы


1.Джон Пол Мюллер, Дебби Валковски, Microsoft Office Visio 2007 для "чайников"- М.: 2008.- 304с

.Бонни Бьяфоре, Visio 2007 Bible- М.:2009.-800с

.Джим Арлоу, Айла Нейдштадт, UML и Унифицированный процесс- М.:2007.-617с

.#"justify">.Дж. Рамбо, UML 2.0. Объектно-ориентированное моделирование и разработка- М.:2007.-544с


МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ Государственное образовательное учреждение высшего профессионального образования «Ижевский государственный технич

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ