Разработка объектной программы для задачи "Аудиторный фонд учебного заведения"

Описание используемых структур данных. Рассмотрение кратких сведений об объектном подходе. Определение созданного формализованного описания разработанных классов. Исследование особенностей демонстрационного модуля. Характеристика структуры проекта.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 27.10.2018
Размер файла 318,6 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ

«УНИВЕРСИТЕТ УПРАВЛЕНИЯ «ТИСБИ»

Факультет «Информационные технологии»

КУРСОВАЯ РАБОТА

по дисциплине «Объектно-ориентированное программирование»

на тему: Разработка объектной программы для задачи «Аудиторный фонд учебного заведения»

Выполнила: студентка

группы ИВТ-611

Петрова Е.И.

Преподаватель:

к.т.н., доц. Козин А.Н.

Казань, 2018 г.

Оглавление

Постановка задачи

1. Описание используемых структур данных

2. Краткие сведенья об объектном подходе

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

4. Описание демонстрационного модуля

5. Описание структуры проекта

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

Приложение

демонстрационный модуль проект данные

Постановка задачи

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

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

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

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

Имена классов, свойств и методов должны носить содержательный смысл и соответствовать информационной задаче

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

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

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

Стандартные контейнеры/коллекции (включая обобщенные классы) разрешается использовать только как дополнение к самостоятельно разработанным классам.

В качестве языка разработки используется Object Pascal и среда разработки Lazarus.

1. Описание используемых структур данных

Реализация списковых структур.

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

Стандартный набор операций со списком включает:

поиск в списке заданного элемента

добавление нового элемента после заданного или перед заданным элементом

удаление заданного элемента

проход по списку от первого элемента к последнему с выполнением заданных действий

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

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

Рассмотрим реализацию не замкнутого двунаправленного списка, без заголовка.

Инициализация списка: pFirst := nil;

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

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

Внутри функции объявляется вспомогательная локальная переменная - pTemp :pListItem адрес текущего элемента списка.

Устанавливается pTemp в адрес первого элемента списка:

Организуется цикл по условию достижения конца списка

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

После завершения цикла формируется отрицательный результат поиска:

Result := nil;

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

Необходимо выполнить два шага:

выделить память с использованием указателя pFirst

записать в адресное поле элемента пустой адрес

Добавление нового элемента перед заданным:

Поиск места вставки

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

После нахождения места вставки выделяем память для нового элемента, используя указатель pNew

Формируем поля нового элемента, в частности:

в поле next заносится адрес заданного элемента

в поле prev заносится адрес предшествующего элемента (берется из поля last)

Изменяем адресное поле prev у заданного элемента на адрес нового элемента

Изменяем адресное поле next у предшествующего элемента на адрес нового элемента

В добавлении нового элемента в упорядоченный список особыми являются ситуации при вставке перед первым элементом и добавление в конец.

Добавление нового элемента перед первым:

Изменяем адресное поле next у нового элемента:

Изменяем указатель First на адрес нового элемента:

Добавление нового элемента в конец списка:

Указатель last адресует последний элемент в списке.

Изменяем адресное поле next у заданного элемента на адрес нового элемента

Формируем поле нового элемента, в частности в поле prev заносится адрес предшествующего элемента

Удаление заданного элемента

Проверка наличия элементов в списке

Поиск удаляемого элемента

Если элемент найден, адресуем его указателем pTemp

Изменяем адресное поле prev у следующего за удаляемым элемента на адрес элемента, предшествующего удаляемому (этот адрес берем из поля prev удаляемого элемента)

Изменяем адресное поле next у элемента, предшествующего удаляемому на адрес элемента, следующего за удаляемым (этот адрес берем из поля next удаляемого элемента)

Обрабатываем удаляемый элемент, используя указатель pTemp

Очередь (Queue) - это последовательность однотипных элементов, характерная тем, что новые элементы в нее добавляются с одного конца, а удаляются с другого.

Очередь работает по принципу “Элемент, помещенный в очередь первым, извлечен будет тоже первым”. Иногда этот принцип обозначается сокращением FIFO (от английского «FirstIn - FirstOut», т.е. «Первым зашел - первым вышел»). Для очереди определяется ее начало (первый элемент в очереди) и конец (последний элемент).

Основные принципы реализации статической очереди на основе массива:

объявляем базовый массив с элементами необходимого типа

объявляем две переменные целого типа - индекс начала очереди First и индекс конца очереди Last.

Будем считать, что очередь-массив заполняется (растет) от первых элементов массива к последним. Тогда индекс First будет определять первую занятую ячейку массива, а индекс Last - первую свободную ячейку. Пустую очередь определим, как First = Last = 1 (если индексация элементов массива начинается с 1).

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

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

Работу с очередью необходимо начинать с ее инициализации (пустая очередь):

First = 1; Last = 1; счетчик = 0;

Алгоритм добавления нового элемента в конец очереди:

проверить возможность добавления (есть ли свободные ячейки?)

добавить элемент в массив по индексу Last

изменить индекс Last на 1

если Last выходит за пределы массива, то установитьLast в 1

увеличить счетчик числа элементов в очереди

Алгоритм удаления элемента из начала очереди:

проверить возможность удаления (есть ли элементы в очереди?)

извлечь элемент из массива по индексу First и выполнить с ним необходимые действия

увеличить индекс First на 1

если First выходит за пределы массива, то установитьFirst в 1

уменьшить счетчик числа элементов в очереди

Алгоритм прохода по элементам очереди отличителен тем, что Индексная переменная цикла должна изменяться от значения First до значения Last-1, причем - с возможным переходом через границу массива.

2. Краткие сведенья об объектном подходе

Объект

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

Класс

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

Для использования классов необходимо объявить объектную переменную. Для каждой переменной вводится уникальное имя и указывается принадлежность к одному из известных классов. Это позволяет называть объектные переменные переменными классового типа.

Инкапсуляция

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

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

Контейнер

Контейнером называется объект, позволяющий хранить и обрабатывать набор некоторых объектов. Вариантами реализации контейнера могут быть на основе:

* на основе массива

* на основе динамических списков разных типов

* на основе поисковых деревьев

* на основе хеш-таблиц

Наследование

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

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

Полиморфизм

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

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

Переопределение методов основано на двух важных понятиях:

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

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

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

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

Интерфейсные классы

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

Существуют некоторые отличия интерфейсных классов от абстрактных классов:

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

абстрактные классы поддерживают только простое наследование, а интерфейсные - множественное;

обычный класс может в качестве родителя иметь только один абстрактный класс, а вот интерфейсов-родителей может быть и несколько;

абстрактный класс может содержать поля данных, а интерфейсный - либо вообще не может, либо только статические неизменяемые поля

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

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

Взаимодействие объектов и классов

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

Различают два способа взаимодействия:

агрегация (композиция)

обобщение (наследование)

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

Обобщение возникает в том случае, когда один из классов описывает некоторое достаточно общее понятие, а другие - более конкретные разновидности этого понятия.

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

Класс «Аудитория»:

TAuditory = class

private

Number: integer; // номер аудитории

SeatsNumber: integer; // количество мест

public

constructor Create(aNumber, aSeatsNumber: integer);

function GetNumber: integer;

function GetSeatsNumber: integer;

procedure SetSeatsNumber(aSeatsNumber: integer);

procedure SetNumber(aNumber: integer);

end;

Класс «Корпус»:

Const

MaxCount = 5; // максимальное кол-во аудиторий в корпусе

Type

TCorps = class

private

Mas: array [1 .. MaxCount] of TAuditory; // массив аудиторий в корпусе

Number: integer; // номер корпуса

CountAudit: integer; // количество аудиторий

First, Last: integer; // индекс первой занятой/первой свободной ячейки

next, prev: TCorps; // ссылка на следующий/предыдущий корпус

public

constructor Create(aNumber: integer);

// метод доступа к аудиториям по номеру в очереди

function GetAuditory(i: integer): TAuditory;

function GetNumber: integer;

function GetCountAudit: integer;

function GetFirst: integer;

function GetLast: integer;

function GetNext: TCorps;

function GetPrev: TCorps;

// метод для вычисления суммарного количества мест

function SummSeatsNumber: integer;

procedure SetNext(aNext: TCorps);

procedure SetPrev(aPrev: TCorps);

procedure SetNumber(aNumber: integer);

// булева для проверки добавления (очередь переполнена)

function AddAuditory(aAuditory: TAuditory): boolean;

function Search(aNumber: integer): TAuditory; // поиск аудитории по номеру

// удаление аудитории из очереди (первой добавленной)

function DeleteAuditory: boolean;

end;

Класс «Учебное заведение»:

TEducatioIinstitution = class

private

Count: integer; // количество корпусов

First: TCorps; // ссылка на первый элемент

public

constructor Create();

function GetFirst: TCorps; // метод доступа к первому элементу в списке

function GetCount: integer; // метод доступа к счётчику элементов в списке

function SummSeatsNumber: integer;

// метод для вычисления суммарного количества мест

procedure AddCorps(aCorpsNew: TCorps); // добавление корпуса

function Search(aNumber: integer): TCorps;

// поиск корпуса по номеру, будет возвращать ссылку на сам корпус/null если не найдем

function DeleteCorps(aNumberSearch: integer): boolean;

// удаление по номеру (False если не нашли удаляемый эл.)

procedure Save(FileName: string);

procedure Load(FileName: string);

end;

4. Описание демонстрационного модуля

При запуске программы появляется следующее окно:

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

В программе используются компоненты:

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

Таблица StringGrid состоит из выделенных серым FixedCols и FixedRows - зафиксированных ячеек-заголовков, и обычных, белых ячеек. Содержимое Fixed ячеек недоступно редактированию, и меняется только программно. За возможность редактирования обычных ячеек отвечает значение свойства Edit в Options.

Компонент StringGrid имеет возможность адресации каждой отдельной ячейки по номеру столбца и строки. Содержимое ячейки (i, j), где где i - номер столбца, j - номер строки, имеет вид

StringGrid1.Cells[i, j] и доступно как для чтения, так и для записи. Здесь, как и всегда, номера столбцов ( i ) и строк ( j ) отсчитываются от 0.

Выделенная ячейка таблицы имеет

номер столбца: StringGrid1.Col

номер строки: StringGrid1.Row

Компонент SaveDialog1 используется для сохранения, а OpenDialog для загрузки структуры в файл.

Компонент класса TSpinEdit предназначен исключительно для ввода целых чисел. Две кнопки, находящиеся в правой части компонента, предоставляют возможность пошагового изменения значения чисел. В этот компонент допускается ввод только цифр и знаков «плюс» (+) и «минус» (-).

Компонент Button это простая командная кнопка. Командная кнопка \ Button используется для реализации в программе команд с помощью обработчика события OnClick этого компонента.

Delphi компонент Label предназначен для отображения статического текста, то есть надписей и меток на Форме, которые не меняются в течение всего времени работы программы. Текст надписи, отображаемый компонентом Label можно изменить только программно.

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

procedure StringGridCorpsClick(Sender: TObject); // заполнение StringGrid с аудиториями - при клике на корпус в StringGrid

procedure ButtonLoadClick(Sender: TObject); // загрузка из файла

procedure ButtonSaveClick(Sender: TObject); // сохранение в файл

procedure ButtonAddCorpsClick(Sender: TObject); // добавление корпуса

procedure ButtonDeleteCorpsClick(Sender: TObject); // удаление корпуса

procedure ButtonSearchAuditoryClick(Sender: TObject); // поиск аудитории

procedure ButtonAddAuditoryClick(Sender: TObject); // добавление аудитории

procedure ButtonDeleteAuditoryClick(Sender: TObject); // удаление аудитории

procedure ButtonSearchCorpsClick(Sender: TObject); // поиск корпуса

procedure TableReload; // заполнение StringGrid с корпусами

procedure FormCreate(Sender: TObject); // обработчик создания формы

procedure UpdateButtonState(); // обновляет состояние кнопок

5. Описание структуры проекта

Проект Lazarus-это несколько связанных между собой файлов.

Главный файл проекта, называется PROJECT1.LPR

В файлах расширением *.pas хранятся программные модули проекта.

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

Файл PROJECT1.RES изначально содержит иконку для проекта. Создается автоматически. Имеет одноименное название с названием проекта.

Исполняемый EXE файл, который создается в процессе компиляции проекта. Если сохранить проект под другим именем, то изменят название и файлы с расширением RES (.pas), который компонуется в окончательный исполняемый файл.

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

1. Бабушкина И.А. Практикум по объектно-ориентированному программированию [Электронный ресурс]/ Бабушкина И.А., Окулов С.М.-- Электрон. текстовые данные. -- М.: БИНОМ. Лаборатория знаний, 2015. -- 367 c

2. Вирт Н. Алгоритмы и структуры данных. -- ДМК Пресс, 2014г. -- 272 c

3. Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж. - Приемы объектно-ориентированного проектирования. Паттерны проектирования- 2013;

4. Касторнова. В. А. Структуры данных и алгоритмы их обработки на языке программирования Паскаль. - БХВ-Петербург 2016 г. -- 298 c

5. Кнут, Д.Э. Искусство программирования. Том 1. Основные алгоритмы -- Вильямс, 2017

6. Коберн Алистер - Быстрая разработка программного обеспечения - 2016;

7. Макконнелл С. - Совершенный код. Мастер-класс - 2014

8. Мейер Б. Объектно-ориентированное программирование и программная инженерия [Электронный ресурс]/ Мейер Б.-- Электрон. текстовые данные. -- М.: Интернет-Университет Информационных Технологий (ИНТУИТ), 2016. -- 285 c.

9. Мейер Б - Инструменты, алгоритмы и структуры данных - 2016

10. Мясникова Н.А. Алгоритмы и структуры данных. Учебное пособие. - КноРус, 2018 г.

11. Попов Е.А. - Экспресс курс программирования в Lazarus - 2014;

12. Санников Е. В. Курс практического программирования в Delphi. Объектно-ориентированное программирование. - Солон-Пресс, 2013 г.

13. Хорев П.Б. Объектно-ориентированное программирование -- Academia, Москва 2012г. -- 448 c.

Приложение

//Главный модуль

unit UMain;

{$mode objfpc}{$H+}

interface

uses

Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,

Grids, Spin, UAuditory, UCorps, UInstitution, Math;

type

{ TFormMain }

TFormMain = class(TForm)

ButtonAddAuditory: TButton;

ButtonAddCorps: TButton;

ButtonDeleteAuditory: TButton;

ButtonDeleteCorps: TButton;

ButtonLoad: TButton;

ButtonSave: TButton;

ButtonSearchAuditory: TButton;

ButtonSearchCorps: TButton;

GroupBox1: TGroupBox;

GroupBox2: TGroupBox;

Label1: TLabel;

Label2: TLabel;

Label3: TLabel;

OpenDialog1: TOpenDialog;

SaveDialog1: TSaveDialog;

SpinEditNew: TSpinEdit;

SpinEditNewAuditory: TSpinEdit;

SpinEditPlace: TSpinEdit;

StringGridAudit: TStringGrid;

StringGridCorps: TStringGrid;

procedure ButtonAddAuditoryClick(Sender: TObject);

procedure ButtonAddCorpsClick(Sender: TObject);

procedure ButtonDeleteAuditoryClick(Sender: TObject);

procedure ButtonDeleteCorpsClick(Sender: TObject);

procedure ButtonLoadClick(Sender: TObject);

procedure ButtonSaveClick(Sender: TObject);

procedure ButtonSearchAuditoryClick(Sender: TObject);

procedure ButtonSearchCorpsClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure StringGridCorpsClick(Sender: TObject);

procedure TableReload;

procedure UpdateButtonState();

private

public

end;

var

FormMain: TFormMain;

aContainer: TEducatioIinstitution;

implementation

{$R *.lfm}

{ TFormMain }

// очистка стринггрида с сохранением заголовка

procedure ClieanStringGrid(aStringGrid: TStringGrid);

var

i: integer;

j: integer;

begin

for i := 0 to aStringGrid.ColCount - 1 do

for j := 1 to aStringGrid.RowCount - 1 do

aStringGrid.Cells[i, j] := '';

end;

// обновляет состоние кнопок

procedure TFormMain.UpdateButtonState();

var

corps: TCorps;

sSearchCorpsName: string;

begin

if aContainer.GetCount = 0 then

begin

ButtonDeleteCorps.Enabled := False;

ButtonSearchCorps.Enabled := False;

ButtonAddAuditory.Enabled := False;

ButtonDeleteAuditory.Enabled := False;

ButtonSearchAuditory.Enabled := False;

end

else

begin

ButtonDeleteCorps.Enabled := True;

ButtonSearchCorps.Enabled := True;

end;

sSearchCorpsName := StringGridCorps.Cells[0, StringGridCorps.Row];

if sSearchCorpsName = '' then

exit;

corps := aContainer.Search(StrToInt(sSearchCorpsName));

if corps = nil then

begin

ButtonAddAuditory.Enabled := False;

ButtonDeleteAuditory.Enabled := False;

ButtonSearchAuditory.Enabled := False;

end

else

begin

ButtonAddAuditory.Enabled := True;

ButtonDeleteAuditory.Enabled := True;

ButtonSearchAuditory.Enabled := True;

end;

end;

// заполнение StringGrid с аудиториями - при клике на корпус в StringGrid

procedure TFormMain.StringGridCorpsClick(Sender: TObject);

var

corps: TCorps;

auditory: TAuditory;

i: integer;

begin

ClieanStringGrid(StringGridAudit);

UpdateButtonState;

if StringGridCorps.Cells[0, StringGridCorps.Row] = '' then

exit;

corps := aContainer.Search((StrToInt(StringGridCorps.Cells[0,

StringGridCorps.Row])));

if corps <> nil then

begin

// установим количество стрк в таблице

StringGridAudit.RowCount :=

Max(corps.GetCountAudit + 1, StringGridAudit.FixedRows + 1);

for i := 1 to corps.GetCountAudit do

begin

auditory := corps.GetAuditory(i);

StringGridAudit.Cells[0, i] := IntToStr(auditory.GetNumber);

StringGridAudit.Cells[1, i] := IntToStr(auditory.GetSeatsNumber);

end;

end;

end;

// заполнение StringGrid с корпусами

procedure TFormMain.TableReload;

var

i: integer;

aCorps: TCorps;

begin

ClieanStringGrid(StringGridCorps);

UpdateButtonState;

// установим количество стрк в таблице

StringGridCorps.RowCount := Math.Max(aContainer.GetCount + StringGridCorps.FixedRows, StringGridCorps.FixedRows+1);

if aContainer.GetCount <> 0 then

begin

aCorps := aContainer.GetFirst;

for i := 1 to aContainer.GetCount do

begin

StringGridCorps.Cells[0, i] := IntToStr(aCorps.GetNumber);

StringGridCorps.Cells[1, i] := IntToStr(aCorps.GetCountAudit);

StringGridCorps.Cells[2, i] := IntToStr(aCorps.SummSeatsNumber);

aCorps := aCorps.GetNext;

end;

StringGridCorps.Row := 1;

end;

UpdateButtonState;

end;

procedure TFormMain.ButtonAddAuditoryClick(Sender: TObject);

var

i: integer;

aCorps: TCorps;

aAuditory: TAuditory;

begin

aCorps := aContainer.Search(StrToInt(StringGridCorps.Cells[0,

StringGridCorps.Row]));

if aCorps = nil then

exit;

aAuditory := TAuditory.Create(SpinEditNewAuditory.Value, SpinEditPlace.Value);

if aCorps.Search(aAuditory.GetNumber) <> nil then

begin

MessageDlg('Номер аудитории не уникален',

mtWarning, [mbOK], 0);

exit;

end;

if aCorps.AddAuditory(aAuditory) = False then

ShowMessage('Нет места! Удалите аудиторию');

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

i := StringGridCorps.Row;

// обновим таблицу, чтоб бы обновить столбец - количество аудиторий в корпусе

TableReload;

// вернем изначальный индексвыбранной строки

StringGridCorps.Row := i;

// обновим таблицу с аудиториями

StringGridCorpsClick(Sender);

end;

// добавление корпуса

procedure TFormMain.ButtonAddCorpsClick(Sender: TObject);

var

aCorps: TCorps;

begin

// проверка уникальности создаваемного корпуса

if aContainer.Search(SpinEditNew.Value) = nil then

begin

aCorps := TCorps.Create(SpinEditNew.Value);

aContainer.AddCorps(aCorps);

TableReload;

end

else

MessageDlg('Номер корпуса не уникален', mtWarning, [mbOK], 0);

end;

// удаление аудитории

procedure TFormMain.ButtonDeleteAuditoryClick(Sender: TObject);

var

aCorps: TCorps;

begin

aCorps := aContainer.Search(StrToInt(StringGridCorps.Cells[0,

StringGridCorps.Row]));

if aCorps <> nil then

begin

if aCorps.DeleteAuditory = False then

MessageDlg('Нечего удалять', mtWarning, [mbOK], 0);

StringGridCorpsClick(Sender);

end;

TableReload;

end;

// удаление корпуса

procedure TFormMain.ButtonDeleteCorpsClick(Sender: TObject);

begin

aContainer.DeleteCorps(StrToInt(StringGridCorps.Cells[0, StringGridCorps.Row]));

TableReload;

StringGridCorpsClick(Sender);

end;

// поиск аудитории

procedure TFormMain.ButtonSearchAuditoryClick(Sender: TObject);

var

k: string;

p, k1: integer;

s: TAuditory;

aCorps: TCorps;

begin

aCorps := aContainer.Search(StrToInt(StringGridCorps.Cells[0,

StringGridCorps.Row]));

if aCorps = nil then

exit;

if aCorps.GetCountAudit = 0 then

begin

TableReload;

ShowMessage('Список пуст! Искать нечего');

exit;

end;

k := InputBox('Поиск',

'Введите номер искомой аудитории:', '1');

if k = '' then

ShowMessage('Ведите номер искомой аудитории');

p := StrToInt(k);

s := aCorps.Search(p);

if s = nil then

begin

ShowMessage('Аудитория не найдена');

exit;

end

else

begin

k1 := StringGridAudit.Cols[0].IndexOf(k);

StringGridAudit.Row := k1;

end;

end;

// поиск корпуса

procedure TFormMain.ButtonSearchCorpsClick(Sender: TObject);

var

k: string;

p, k1: integer;

s: TCorps;

begin

if aContainer.GetCount = 0 then

begin

TableReload;

ShowMessage('Список пуст! Искать нечего');

exit;

end;

k := InputBox('Поиск',

'Введите номер искомого корпуса:', '1');

if k = '' then

ShowMessage('Ведите номер искомого корпуса');

p := StrToInt(k);

s := aContainer.Search(p);

if s = nil then

begin

ShowMessage('корпус не найдено');

exit;

end

else

begin

k1 := StringGridCorps.Cols[0].IndexOf(k);

if k1 = -1 then

exit;

if StrToInt(StringGridCorps.Cells[0, k1]) = s.GetNumber then

StringGridCorps.Row := k1;

end;

end;

// обработчик сокорпуса формы

procedure TFormMain.FormCreate(Sender: TObject);

begin

aContainer := TEducatioIinstitution.Create();

StringGridCorps.Cells[0, 0] := 'Номер';

StringGridCorps.Cells[1, 0] := 'Кол-во аудиторий';

StringGridCorps.Cells[2, 0] := 'Всего мест';

StringGridAudit.Cells[0, 0] := 'Номер';

StringGridAudit.Cells[1, 0] := 'Число мест';

UpdateButtonState();

end;

// загрузка из файла

procedure TFormMain.ButtonLoadClick(Sender: TObject);

begin

if OpenDialog1.Execute then

begin

aContainer := TEducatioIinstitution.Create();

aContainer.Load(OpenDialog1.FileName);

TableReload;

StringGridCorpsClick(Sender);

end;

end;

// сохранние в файл

procedure TFormMain.ButtonSaveClick(Sender: TObject);

begin

if SaveDialog1.Execute then

aContainer.Save(SaveDialog1.FileName);

end;

end.

// Класс Учебное заведение

unit UInstitution;

{$mode objfpc}{$H+}

interface

uses

Classes, SysUtils, UAuditory, UCorps;

type

TEducatioIinstitution = class

private

Count: integer; // количество корпусов

First: TCorps; // ссылка на первый элемент

public

constructor Create();

function GetFirst: TCorps;

// метод доступа к первому элементу в списке

function GetCount: integer;

// метод доступа к счетку элементов в списке

function SummSeatsNumber: integer;

// метод для вычисления сумарного количечства мест

procedure AddCorps(aCorpsNew: TCorps); // добавление корпуса

function Search(aNumber: integer): TCorps;

// поиск корпуса по номеру, будет возвращать ссылку на сам корпус/null если не найдем

function DeleteCorps(aNumberSearch: integer): boolean;

// удаление по номеру (False если не нашли удаляемый эл.)

procedure Save(FileName: string);

procedure Load(FileName: string);

end;

implementation

constructor TEducatioIinstitution.Create();

begin

First := nil;

Count := 0;

end;

function TEducatioIinstitution.SummSeatsNumber: integer;

var

temp: TCorps;

sum: integer;

begin

sum := 0;

temp := First;

while (temp <> nil) do

begin

sum := sum + temp.SummSeatsNumber;

end;

Result := sum;

end;

function TEducatioIinstitution.GetCount: integer;

begin

Result := Count;

end;

function TEducatioIinstitution.GetFirst: TCorps;

begin

Result := First;

end;

procedure TEducatioIinstitution.AddCorps(aCorpsNew: TCorps);

var

temp, last: TCorps;

begin

temp := First;

// если добавляем первый - список пуст

if temp = nil then

begin

First := aCorpsNew;

Inc(Count);

end

else

// еесли список заполнен

begin

// ищем место вставки

while (temp <> nil) and (temp.GetNumber < aCorpsNew.GetNumber) do

begin

last := temp;

temp := temp.GetNext;

end;

// добавление в конец

if temp = nil then

begin

last.SetNext(aCorpsNew);

aCorpsNew.SetPrev(last);

Inc(Count);

exit;

end;

// добавление перед первым

if temp = First then

begin

aCorpsNew.SetNext(First);

First := aCorpsNew;

end

else

begin

// добавление в середну

aCorpsNew.SetNext(temp);

aCorpsNew.SetPrev(last);

last.SetNext(aCorpsNew);

temp.SetPrev(aCorpsNew);

end;

Inc(Count);

end;

end;

function TEducatioIinstitution.Search(aNumber: integer): TCorps;

var

temp: TCorps;

begin

Result := nil;

temp := First;

while temp <> nil do

begin

if temp.GetNumber = aNumber then

begin

Result := temp;

break;

end

else

temp := temp.GetNext;

end;

end;

function TEducatioIinstitution.DeleteCorps(aNumberSearch: integer): boolean;

var

temp: TCorps;

begin

Result := False;

if Count = 0 then

exit; // на пустоту

temp := Search(aNumberSearch);

if temp = First then

begin // удаление первого

First := temp.GetNext;

Dec(Count);

FreeAndNil(temp);

Result := True;

exit;

end;

if temp = nil then

exit;

if temp.GetNext = nil then

begin // удаление последнего

temp.GetPrev.SetNext(nil);

Dec(Count);

FreeAndNil(temp);

Result := True;

exit;

end;

temp.GetNext.SetPrev(temp.GetPrev);

temp.GetPrev.SetNext(temp.GetNext);

FreeAndNil(temp);

Dec(Count);

Result := True;

end;

procedure TEducatioIinstitution.Save(FileName: string);

var

F: TextFile;

temp: TCorps;

i: integer;

begin

AssignFile(F, FileName); // ассоциируем файл и переменную

rewrite(F); // открываем файл для записи

temp := First;

while temp <> nil do

begin

writeln(F, temp.GetNumber); // номер корпуса

for i := 1 to temp.GetCountAudit do

begin

writeln(F, temp.GetAuditory(i).GetNumber);

writeln(F, temp.GetAuditory(i).GetSeatsNumber);

end;

writeln(F, 'Corps');

temp := temp.GetNext;

end;

CloseFile(F); // закрываем файл

end;

procedure TEducatioIinstitution.Load(FileName: string);

var

F: TextFile;

corps: TCorps;

auditory: TAuditory;

s: string;

begin

AssignFile(F, FileName);

// ассоциируем файл и переменную

reset(F); // открываем файл для чтения

while not EOF(F) do

begin // цикл до конца файла

ReadLn(F, s); // считываем номер корпуса

corps := TCorps.Create(StrToInt(s));

AddCorps(corps); // добавляем корпус

ReadLn(F, s);

while (s <> 'Corps') do

begin

auditory := TAuditory.Create(StrToInt(s), 0);

ReadLn(F, s);

auditory.SetSeatsNumber(StrToInt(s));

corps.AddAuditory(auditory);

ReadLn(F, s);

end;

end;

CloseFile(F);

end;

end.

// Класс корпус

unit UCorps;

{$mode objfpc}{$H+}

interface

uses

Classes, SysUtils, UAuditory;

const

MaxCount = 5; // максимальное кол-во аудиторий в корпусе

type

TCorps = class

private

Mas: array [1 .. MaxCount] of TAuditory;

// массив аудиторий в корпусе

Number: integer; // номер корпуса

CountAudit: integer; // количество аудиторий

First, Last: integer;

// индекс первой занятой/первой свободной ячейки

Next, prev: TCorps;

// ссылка на следующеий/предыдущий корпус

public

constructor Create(aNumber: integer);

// метод доступа к аудиторий по номеру в очереди

function GetAuditory(i: integer): TAuditory;

function GetNumber: integer;

function GetCountAudit: integer;

function GetFirst: integer;

function GetLast: integer;

function GetNext: TCorps;

function GetPrev: TCorps;

// метод для вычисления сумарного количечства мест

function SummSeatsNumber: integer;

procedure SetNext(aNext: TCorps);

procedure SetPrev(aPrev: TCorps);

procedure SetNumber(aNumber: integer);

// булева для проверки добавления (очередь переполнена)

function AddAuditory(aAuditory: TAuditory): boolean;

function Search(aNumber: integer): TAuditory;

// поиск аудитории по номеру

// удаление аудитории из очереди (первой добавленной)

function DeleteAuditory: boolean;

end;

implementation

constructor TCorps.Create(aNumber: integer);

var

i: integer;

begin

CountAudit := 0;

First := 1;

Last := 1;

Next := nil;

prev := nil;

Number := aNumber;

for i := 1 to MaxCount do

Mas[i] := nil;

end;

// возвращает экземпляр объекта аудитории по номеру в очереди

function TCorps.GetAuditory(i: integer): TAuditory;

begin

// проверяем не выходит ли индекс за пределы допустимыхзначений

if i > CountAudit then

exit;

if (First + i - 1) > MaxCount then

// с переходом через границу

Result := Mas[i + First - MaxCount - 1]

else

// если не нужен переход

Result := Mas[i + First - 1];

end;

function TCorps.GetNumber: integer;

begin

Result := Number;

end;

function TCorps.SummSeatsNumber: integer;

var

i, summ: integer;

begin

summ := 0;

for i := 1 to CountAudit do

summ := summ + GetAuditory(i).GetSeatsNumber;

Result := summ;

end;

function TCorps.GetCountAudit: integer;

begin

Result := CountAudit;

end;

function TCorps.GetFirst: integer;

begin

Result := First;

end;

function TCorps.GetLast: integer;

begin

Result := Last;

end;

function TCorps.GetNext: TCorps;

begin

Result := Next;

end;

function TCorps.GetPrev: TCorps;

begin

Result := prev;

end;

procedure TCorps.SetNext(aNext: TCorps);

begin

Next := aNext;

end;

procedure TCorps.SetPrev(aPrev: TCorps);

begin

prev := aPrev;

end;

procedure TCorps.SetNumber(aNumber: integer);

begin

Number := aNumber;

end;

function TCorps.AddAuditory(aAuditory: TAuditory): boolean;

begin

Result := False;

if CountAudit = MaxCount then

exit;

Mas[Last] := aAuditory;

Inc(Last);

if Last > MaxCount then

Last := 1;

Inc(CountAudit);

Result := True;

end;

function TCorps.Search(aNumber: integer): TAuditory;

var

i: integer;

begin

Result := nil;

if (CountAudit > 0) then

for i := 1 to CountAudit do

if GetAuditory(i).GetNumber = aNumber then

begin

Result := Mas[i];

break;

end;

end;

function TCorps.DeleteAuditory: boolean;

begin

Result := False;

if CountAudit = 0 then

exit;

Mas[First] := nil;

Inc(First);

if First > MaxCount then

First := 1;

Dec(CountAudit);

Result := True;

end;

end.

// Класс аудитории

unit UAuditory;

interface

uses

Classes, SysUtils;

Type

TAuditory = class // класс аудитории

private

Number: integer; // номер аудитории

SeatsNumber: integer; // количество мест

public

constructor Create(aNumber, aSeatsNumber: integer);

function GetNumber: integer;

function GetSeatsNumber: integer;

procedure SetSeatsNumber(aSeatsNumber: integer);

procedure SetNumber(aNumber: integer);

end;

implementation

constructor TAuditory.Create(aNumber, aSeatsNumber: integer);

begin

Number := aNumber;

SeatsNumber := aSeatsNumber;

end;

function TAuditory.GetNumber: integer;

begin

result := Number;

end;

function TAuditory.GetSeatsNumber: integer;

begin

result := SeatsNumber;

end;

procedure TAuditory.SetSeatsNumber(aSeatsNumber: integer);

begin

SeatsNumber := aSeatsNumber;

end;

procedure TAuditory.SetNumber(aNumber: integer);

begin

Number := aNumber;

end;

end.

Размещено на Allbest.ru

...

Подобные документы

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

    курсовая работа [532,7 K], добавлен 20.07.2014

  • База данных для автоматизации работы информационно-технической службы учебного заведения в области учета оборудования. Даталогическое проектирование. Ключевые поля и индексы. Ограничения бизнес правил. Пользовательский интерфейс. Запросы к базе данных.

    курсовая работа [2,2 M], добавлен 12.02.2013

  • Разработка программы "Игроки КХЛ 2012-2013" на языке С++ с использованием классов списков структур для обработки данных. Описание глобальных переменных, разработанных функций. Главное меню программы. Чтение данных из файла, их просмотр и сохранение.

    курсовая работа [2,2 M], добавлен 17.03.2016

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

    реферат [27,4 K], добавлен 20.04.2019

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

    курсовая работа [1,4 M], добавлен 07.08.2013

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

    курсовая работа [1,1 M], добавлен 14.08.2014

  • Создание приложения, которое на вход получает компьютерную структуру, обрабатывает ее и выводит на экран. Краткое описание используемых пространств имен и классов. Файлы программного модуля Beta. Пример его работы, порядок подключения к Веб-странице.

    дипломная работа [1,3 M], добавлен 06.07.2015

  • Проектирование программного обеспечения для классифицирования выпускников высшего учебного заведения. Выбор системы управления базами данных и языка программирования. Разработка структуры данных, схема базы данных. Реализация программного комплекса.

    дипломная работа [2,4 M], добавлен 27.03.2013

  • Разработка СУБД - программного модуля для систематизации, хранения и обработки сведений о работниках лаборатории. Технологический процесс машинной реализации задачи, составление алгоритма, описание переменных процедур и функций. Листинг программы.

    курсовая работа [1,7 M], добавлен 11.01.2013

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

    дипломная работа [1,3 M], добавлен 25.12.2014

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

    курсовая работа [687,2 K], добавлен 03.10.2013

  • Проектирование программного модуля: сбор исходных материалов; описание входных и выходных данных; выбор программного обеспечения. Описание типов данных и реализация интерфейса программы. Тестирование программного модуля и разработка справочной системы.

    курсовая работа [81,7 K], добавлен 18.08.2014

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

    курсовая работа [1,3 M], добавлен 09.09.2012

  • Проектирование базы данных "Учебные заведения Петербурга". Создание и обработка базы данных в среде Excel. Вывод сведений обо всех учебных заведениях, сгруппированных по статусу учебного заведения, с подсчётом средней заработной платы преподавателей.

    курсовая работа [1,7 M], добавлен 27.02.2015

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

    курсовая работа [488,7 K], добавлен 08.09.2010

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

    дипломная работа [5,8 M], добавлен 28.06.2011

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

    курсовая работа [1,2 M], добавлен 25.04.2011

  • Проектирование модульной структуры программы сетевого мессенджера, назначение модуля "frmMsg". Разработка главной формы и интерфейса пользователя программы. Проектирование модуля формы "About". Разработка методики тестирования и отладка программы.

    курсовая работа [606,7 K], добавлен 19.01.2012

  • Исследование особенностей разработки программы на основе Microsoft Aсcess 2003. Создание главной формы проекта и механизма экспорта данных в приложение Microsoft Word на основе компонентов OLE Automation. Описания реализации задачи при помощи Delphi.

    курсовая работа [2,0 M], добавлен 09.10.2012

  • Практические аспекты использования прикладного программного обеспечения при разработке базы данных "Аудиторный фонд ГБОУ СПО "Старооскольский педагогический колледж". Системы управления базами данных. Описание и функциональные возможности приложения.

    курсовая работа [360,4 K], добавлен 07.10.2014

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.