- PVSM.RU - https://www.pvsm.ru -
Решил выложить описание и свою программу по составлению расписаний от 2001 года. В моём ВУЗе, на сегодняшний день, ей пользуются практически все крупные факультеты. Вкратце: она может быть и редактором и составлять расписание полностью автоматически или частично для выбранных элементов, сохраняет свои данные в формате Microsoft Access 2000, экспорт расписания групп, преподавателей и аудиторий в виде таблиц Microsoft Excel 2000 и сама написана с использованием MFC 4.2.
Мое глубокое убеждение, что создать программу по составлению расписания для ВУЗов и заработать на ее распространении невозможно, если у Вас нет лапы там наверху и все ВУЗы просто не обяжут ее покупать. Но разработав общее для всех ядро, программисты «на местах» смогут это сделать в той или иной степени.
Думаю, этот топик, с точки зрения разработки всем известной задачи, будет интересен для прочтения практически всем.
До 2001 года писал только программы связанные с научными вычислениями. Программирование графического интерфейса пользователя только смотрел, но не было реальных задач. Аналогично не учил, я по образованию механик, специализировался в аэрогидродинамике, и не знал ничего о СУБД, как построить с ними соединение или как сделать экспорт в Microsoft Excel. Не буду описывать все возникающие на работе пертурбации, но в их результате в совершенно инициативном порядке решил написать программу по составлению расписаний. Я понимал, что те программисты, которые есть в моей организации, ее никогда не сделают реально работающей, из-за ее довольно сложной логики. Для меня же был риск в программировании интерфейса пользователя, работа с СУБД и т.д. Поскольку испытываю просто патологическое неприятие продуктов фирмы Borland (опыт 3-х летний работы), решил ориентироваться на Microsoft. Linux-ом пользовался уже до этого 3-4 года, но там в тот момент времени не было стандартного GUI и нужно было бы ставить его на рабочие
места, что еще большая проблема. Разработка заняла реального времени примерно 2 месяца. При написании, из-за сложной логики, очень активно использовались Тройки Хоара [1]. Ниже описание самой программы и мои предложения.
Программа предназначена для автоматизации процесса составления расписаний занятий в ВУЗах. Она обладает во-первых, возможностью редактирования расписания, а во-вторых его автоматической достройки. Интерфейс программы копирует стандартный проводник Windows. Это, кроме удобства представления информации на экране компьютера, позволяет пользоваться программой без специальной подготовки.

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

Или с помощью панели инструментов, выбирая иконку нужного окна кликом левой кнопки мыши.

Панель инструментов можно включить с помощью меню.

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

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

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

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

Справа от окна групп находится расписание занятий связанное с выделенной группой.

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

Справа от окна преподавателей находится расписание занятий связанное с выделенным преподавателем.

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

Справа от окна аудиторий находится расписание занятий связанное с выделенной аудиторией.

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

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

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

При этом принимаются следующие правила. При перетаскивании папок проведение занятие устанавливается для для всех групп и преподавателей входящих в перетаскиваемые папки. Папка же аудиторий задает закрепленные за занятием предметы. При составлении расписания будет выбрана одна из аудиторий в папке.
Двойной клик мыши, нажатие клавиш Enter или пробел приведут к выделению в нижних окнах связанных с занятием групп, преподавателей и аудиторий. Аналогичные изменения происходят также в связанных с
ними окнами групп, преподавателей и аудиторий.
Замечание
С занятием необязательно связывать группы, преподавателей и аудитории. Любой из этих элементов может отсутствовать. Например неизвестно имя преподавателя, который будет проводит занятие.
Группы можно условно разделить на два больших множества:

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

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

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

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

Папка с названием «Преподаватели по предметам» содержит элементы трех типов:

Ссылки позволяют группировать преподавателей согласно их назначению или если они проводят вместе одно занятие. Например можно объединить заведующих кафедр в одну папку и назначить для них занятие «заседание ученого совета».
Создание и редактирование папок и преподавателей проводится с использованием контекстного меню. Для этого необходимо нажать правую кнопку мыши на выделенном элементе. Для копирования, перемещения и создания ссылок можно использовать контекстное меню или перетаскивая выбранный элемент мышкой. Если при перетаскивание нажать Ctrl, то если возможно будет создана копия элемента. В любой папке элементы упорядочиваются по алфавиту. Два разных элемента в папке не могут иметь одинаковое название. Если печатное название отсутствует, то выбирается в качестве печатного само название. Печатное название папки добавляется к имени преподавателя.
Аудитории также можно условно разделить на две большие группы:

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

Данная возможность отсутствует в программе в связи с защитой от несанкционированного использования (я в конце расскажу как обойти мою защиту).
Папка с названием «Аудитории по предметам» содержит элементы трех типов:

Ссылки позволяют группировать аудитории согласно их назначению. Например аудитория имея ссылку в папке «Практические» может использоваться для проведения практических занятий и имея ссылку в папке «Лекционные» может использоваться для чтения спецкурсов. В результате можно создавая папки с нужным названием с имитировать любые свойства находящихся в ней аудиторий.
Создание и редактирование аудиторий и объединение их в папки запрещено в программе в связи с защитой от несанкционированного использования(я в конце расскажу как обойти мою защиту). Имеется возможность лишь
внесения изменений в комментарий.
Аудитории, переходы между которыми можно выполнить за перемену можно консолидировать. По умолчанию все аудитории консолидированы. Создание и редактирование папок проводится с использованием контекстного меню. Для этого необходимо нажать правую кнопку мыши на выделенном элементе. Для копирования, перемещения и создания ссылок можно использовать контекстное меню или перетаскивая выбранный элемент мышкой. Если при перетаскивание нажать Ctrl, то если возможно будет создана копия элемента.
В любой папке элементы упорядочиваются по алфавиту. Два разных элемента в папке не могут иметь одинаковое название. Если печатное название отсутствует, то выбирается в качестве печатного само название. Печатное название папки добавляется к имени аудитории. Например печатное название «9 к. » добавится ко всем печатным именам аудиторий в «9 корпусе».
Структура данных представлены в виде SQL совместимого с Microsoft Access.
CREATE TABLE T_audience (
[index] INTEGER NOT NULL PRIMARY KEY,
is_folder BIT NOT NULL,
name VARCHAR(60) NOT NULL,
print_name VARCHAR(30) NULL,
comment VARCHAR(255) NULL,
owner INTEGER NOT NULL REFERENCES T_audience([index])
ON UPDATE CASCADE ON DELETE CASCADE,
consolidate INTEGER NOT NULL REFERENCES T_audience([index])
ON UPDATE CASCADE ON DELETE CASCADE,
cipher BINARY(60),
CONSTRAINT name UNIQUE(name, owner)
)
CREATE TABLE T_audience_link (
[index] INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(60) NOT NULL,
comment VARCHAR(255) NULL,
owner INTEGER NOT NULL REFERENCES T_audience_link([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT name UNIQUE(name, owner)
)
CREATE TABLE T_link_audience (
link INTEGER NOT NULL REFERENCES T_audience([index])
ON UPDATE CASCADE ON DELETE CASCADE,
owner INTEGER NOT NULL REFERENCES T_audience_link([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT owner UNIQUE(link, owner)
)
CREATE TABLE T_forbid_audience (
[day] TINYINT NOT NULL,
par TINYINT NOT NULL,
num_den BIT NOT NULL,
link INTEGER NOT NULL REFERENCES T_audience([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT forbid UNIQUE([day], par, num_den, link)
)
CREATE TABLE T_teacher (
[index] INTEGER NOT NULL PRIMARY KEY,
is_folder BIT NOT NULL,
name VARCHAR(60) NOT NULL,
print_name VARCHAR(30) NULL,
comment VARCHAR(255) NULL,
owner INTEGER NOT NULL REFERENCES T_teacher([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT name UNIQUE(name, owner)
)
CREATE TABLE T_teacher_link (
[index] INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(60) NOT NULL,
comment VARCHAR(255) NULL,
owner INTEGER NOT NULL REFERENCES T_teacher_link([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT name UNIQUE(name, owner)
)
CREATE TABLE T_link_teacher (
link INTEGER NOT NULL REFERENCES T_teacher([index])
ON UPDATE CASCADE ON DELETE CASCADE,
owner INTEGER NOT NULL REFERENCES T_teacher_link([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT owner UNIQUE(link, owner)
)
CREATE TABLE T_forbid_teacher (
[day] TINYINT NOT NULL,
par TINYINT NOT NULL,
num_den BIT NOT NULL,
link INTEGER NOT NULL REFERENCES T_teacher([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT forbid UNIQUE([day], par, num_den, link)
)
CREATE TABLE T_group (
[index] INTEGER NOT NULL PRIMARY KEY,
is_folder BIT NOT NULL,
is_separation BIT NOT NULL,
name VARCHAR(60) NOT NULL,
print_name VARCHAR(30) NULL,
comment VARCHAR(255) NULL,
owner INTEGER NOT NULL REFERENCES T_group([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT name UNIQUE(name, owner)
)
CREATE TABLE T_group_link (
[index] INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(60) NOT NULL,
comment VARCHAR(255) NULL,
owner INTEGER NOT NULL REFERENCES T_group_link([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT name UNIQUE(name, owner)
)
CREATE TABLE T_link_group (
link INTEGER NOT NULL REFERENCES T_group([index])
ON UPDATE CASCADE ON DELETE CASCADE,
owner INTEGER NOT NULL REFERENCES T_group_link([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT owner UNIQUE(link, owner)
)
CREATE TABLE T_forbid_group (
[day] TINYINT NOT NULL,
par TINYINT NOT NULL,
num_den BIT NOT NULL,
link INTEGER NOT NULL REFERENCES T_group([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT forbid UNIQUE([day], par, num_den, link)
)
CREATE TABLE T_subject (
[index] INTEGER NOT NULL PRIMARY KEY,
is_folder BIT NOT NULL,
name VARCHAR(60) NOT NULL,
print_name VARCHAR(30) NULL,
comment VARCHAR(255) NULL,
owner INTEGER NOT NULL REFERENCES T_subject([index])
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT name UNIQUE(name, owner)
)
CREATE TABLE T_lesson (
owner INTEGER NOT NULL REFERENCES T_subject([index])
ON UPDATE CASCADE ON DELETE CASCADE,
type TINYINT NOT NULL,
num_den BIT NOT NULL,
lenght TINYINT NOT NULL,
is_group TINYINT NOT NULL,
[group] INTEGER,
is_teacher TINYINT NOT NULL,
teacher INTEGER,
is_aud_aside TINYINT NOT NULL,
aud_aside INTEGER,
nda TINYINT,
[day] TINYINT,
par TINYINT,
audience INTEGER,
staging BIT
)
Это был мой первый опыт создания реляционной БД.
Настройка параметров влияющих на составление расписания осуществляется в главном меню.

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

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

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

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

Экспорт расписания осуществляется для выделенного элемента, например кафедры или папки 1 курса, через главное меню. Расписание соответственно сохраняется по группам преподавателям и аудиториям. Их названия присваиваются соответствующим листам Excel.

Защита основана на шифровании аудиторий поэтому программа [2] содержит два exe-шника. Одним, как следует из его названия, нужно занести все аудитории, а затем пользоваться вторым.
В 2002 исходники были потеряны, проблема с компьютером, но нисколько не жалею об этом. Я стараюсь жить по принципу: обращай вред в пользу. Меня давно просят усовершенствовать программу, но я страшно загружен по науке. Поскольку я бедный ученый, то должен эпизодически подрабатывать на
стороне. Научные гранты это копейки и я их трачу только на командировки, на зарплату просто бессмысленно. На этой задаче толком не заработаешь, а время она отнимет много.
Поэтому предлагаю следующие решение (набросок).
PS. По результатом обсуждения буду менять содержание топика.
Автор: bya
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/11603
Ссылки в тексте:
[1] Тройки Хоара: http://ru.wikipedia.org/wiki/%D0%9B%D0%BE%D0%B3%D0%B8%D0%BA%D0%B0_%D0%A5%D0%BE%D0%B0%D1%80%D0%B0
[2] программа: http://invo.jinr.ru/ginv/schedule.zip
[3] ГОСТ Р ИСО/МЭК 26300-2010. Госстандарт России (01.06.2011): http://ru.wikipedia.org/wiki/OpenDocument
[4] ODFPY: http://opendocumentfellowship.com/projects/odfpy
Нажмите здесь для печати.