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

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

·        Переход назад.

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

·        Переход к курсору.

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

·        Добавление меток.

Используется для того, чтобы выделить цветом определенный элемент. Таким образом, во время отладки при появлении элемента в списке, вы сразу заметите его. [12]

·        Вычисление выражений.

Во время отладки можно вычислить любое выражение. [12]

·        Точки останова.

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

·        Замена во время режима отладки.

В результате того, что ВМ (Виртуальная машина) Java поддерживает HotSwap, существует возможность вносить изменения прямо в процессе отладки. При этом перезагружаются измененные классы.[12]

4.3 Проектирование структур данных и алгоритмов

.3.1 Общий алгоритм программы

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

) Получение данных от пользователя.

) Проверка данных на корректность.

) Составление листа запросов.

) Произведение опроса нужных ресурсов согласно листу.) На каждом шаге - получение данных с требуемых ресурсов.) Обработка полученных данных.

) Составление рейтинга на основе всех результатов.

) Вывод результатов в отчет.

4.3.2 Алгоритм работы отдельных стадий выполнения программы

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

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

) Проверка соответствия количества указанных баллов, количеству задач.

) Проверка наличия идентификаторов у инспектируемых студентов для заданных ресурсов.

) Проверка корректности ИД (только цифры).

) Проверка корректности номеров задач (только цифры и запятые).

) Проверка наличия временного интервала.

) Проверка наличия задач и их источников.

Если ПП обнаружит ошибку в данных, то выведет окно со списком найденных ошибок. Пока пользователь их не исправит, он не сможет получить отчет.

Второй стадией является составление списка запросов, которые ПП будет отправлять требуемым ресурсам:

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

) Создание данных для запроса (один запрос хранит в себе ИД, ресурс, номер требуемой задачи).

) Запись запроса в лист запросов.

Третья стадия - получение результатов на основе листа запросов, на ней производятся следующие действия:

) Перебирая лист запросов, вызываем требуемый ресурс, передав ему данные для запроса.

) Получаем страницу, передаем её соответствующему парсеру.

) Получаем от парсера лист с результатами по текущей задаче.

) Заносим этот лист в хеш таблицу, где ключ ФИО, следующий ключ это номер задачи с префиком (зависит от источника).

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

На выходе получаем:

) Хеш-таблицу с задачами, решенными в срок.

) Хеш-таблицу с задачами, решенными вне срока.

) Хеш-таблицу с количеством попыток.

) Хеш-таблицу с общим количеством полученных баллов (если рейтинг составляется на их основе).

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

) Хеш-таблицу с местом конкретного участника (на случай если кол-во баллов или решенных задач одинаково, одного отсортированного листа будет недостаточно).

И завершающая стадия - это составление отчета, на основе данных, полученных на четвертой стадии.

Здесь алгоритм работы следующий:

) Получаем шаблон отчета.

) Подготавливаем шаблон - вставляем номера задач с префиксом в качестве заголовков столбца.

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

) Сохраняем отчет в том месте, где указывает пользователь.

4.3.3 Проектирование основных классов

·        Парсеры.

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

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

·        Классы составления GET запросов к сайтам.

У этих классов есть общий родитель, с методом, возвращающим строку GET запроса на основе данных для этого запроса

Каждый конкретный класс работает с определенным сайтом. Внутри себя хранит шаблон для составления GET запроса. Он устанавливает данные для запроса в нужные параметры и возвращает уже готовый GET запрос.

·        Класс сбора результатов по сайтам.

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

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

·        Класс анализа полученных результатов.

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

·        Класс составления отчета.

Работает с шаблоном отчета. В его функционал входят задачи:

) Подготовка шаблона (выставление заголовков задач с префиксом).

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

) Выдача отчета в виде строки.

4.4 Проектирование пользовательского интерфейса


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

·        ФИО инспектируемых студентов для вставки в отчет.

·        Их ИД на требуемых ресурсах.

·        Номера задач с указанием источника.

·        Разбалловка задач (за исключением сайта кафедры).

·        Период, в течении которого задачи должны были быть решены.

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

·        Вид составления рейтинга.

Чтобы занести эти данные, в интерфейсе должны содержаться элементы, приведенные в табл. 1:

Смысловое значение

Вид интерфейса

ФИО, ИД для разных ресурсов

Таблица, поля для добавления новых строк в таблицу

Номера задач, разбалловка, источник

Таблица, поля для добавления новых строк в таблицу

Период

Календарь

Язык

Текстовое поле

Табл.1

Также должны быть функциональные элементы - кнопки, которые позволяют совершать пользователю следующие действия:

·        Добавить строку в таблицу (на каждую таблицу).

·        Удалить строку из таблицы (на каждую таблицу).

·        Получить отчет.

Удобство привнесет наличие меню, которое будет содержать пункты:

·        Сохранить/загрузить курс.

·        Сохранить/загрузить список инспектируемых студентов.

·        Инструкция.


Вкладка 1

Вкладка 2

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

Таблица задач. Кнопки добавить, удалить. Текстовые поля ФИО, ID timus, ID acmp, ID atpp.

Общее

Меню (сохранить/загрузить курс, сохранить/загрузить список, инструкция) Календари: начало курса, конец курса Текстовое поле: язык программирования Выпадающий список: вид рейтинга

Табл. 2

5. Реализация ПП

.1 Особенности реализации системы


Согласно проекту ПП, реализуем необходимые классы и структуры.

Приведем набор реализованных классов в виде таблицы, см. табл.3

Название класса (набора классов)

Описание

Родитель/интерфейс

Потомок


HttpGetQuery

HttpGetAcmp

Строит запрос для acmp


HttpGetAtpp

Строит запрос для atpp


HttpGetTimus

Строит запрос для timus

HtmlParser

AcmpParser

Парсер сайта acmp


AtppParser

Парсер сайта atpp


AtppPointsParser

Парсер сайта atpp (достает баллы у задач)


TimusParser

Парсер сайта timus

-

ResultMapper

Отвечает за получение результатов

-

ResultItem

Сущность одного результата, соответствует строке из таблицы результатов проверки с сайта

-

TaskList

Составляет лист из всех задач с указанием источника

-

Tasks

Сущность: содержит источник, массив номеров задач и баллов к ним

-

User

Сущность, содержит ФИО и ИД для сайтов

-

UserList

Составляет общий лист испытуемых

-

ControllerMain

Отвечает за главный интерфейс

-

ControllerErrorMS

Отвечает за интерфейс отображения ошибок

-

DataChecker

Проверяет данные введенные пользователем на корректность

-

InternetConnector

Устанавливает соединение с сайтом, возвращает страницу в виде String

-

Main

Главный класс, отвечает за запуск приложения

-

Points

Сущность для быстрого доступа к баллам, которые можно получить за решение конкретной задачи

-

QueryData

Сущность, содержит все необходимое для построения GET запроса

-

Строит лист сущностей QueryData, на основе UserList и TasksList

-

ReportBuilder

Занимается построением отчета

-

Template

Содержит в себе шаблон отчета

-

TemplateSaver

Класс-сущность для сохранения списков и курсов

-

Validator

Хранит в себе фильтры, методы проверки

Табл.3

Приведем код некоторых классов и методов:

public class AcmpParser extends HtmlParser {static final int INDEX_DATE = 1;static final int INDEX_TASK_NUMBER = 3;static final int INDEX_LANG = 4;static final int INDEX_STATUS = 5;static HttpGetAcmp httpGetAcmp = new HttpGetAcmp();

/**

* Конструктор, формирует лист с результатами {@link ResultItem}

*

* @param queryData

*/AcmpParser(QueryData queryData) {(queryData, httpGetAcmp);();();

}void createResultItemList() {(table.size() != 0) {(Element elem : table) {resultItem = new ResultItem()

.setTaskNum(getTaskNum(elem, INDEX_TASK_NUMBER))

.setStatus(getStatus(elem, INDEX_STATUS))

.setLang(getLanguage(elem, INDEX_LANG))

.setDate(getDate(elem))

.setSiteName(ACMP);(resultItem);

}

} else {resultItem = new ResultItem();.setStatus("none");(resultItem);

}

}Date getDate(Element elem) {{DateFormat.getInstance().parse(getTbByIndex(elem, INDEX_DATE).text());

} catch (ParseException e) {.printStackTrace();

}new Date();

}void addResultAll() {elements1 = document.getElementsByClass("gray");elements2 = document.getElementsByClass("white");page = 1;(!elements1.isEmpty() || !elements2.isEmpty()) {urlNextPage = urlSite + "&page=" + page;<Element> tempList = new ArrayList<>();.addAll(elements1.subList(0, elements1.size()));.addAll(elements2.subList(0, elements2.size()));(Element elem : tempList) {(isRequiredLang(elem, INDEX_LANG) || ControllerMain.language.isEmpty()) {.add(elem);

}

}= Jsoup.parse(ic.getHTML(urlNextPage));= document.getElementsByClass("gray");= document.getElementsByClass("white");

page++;

}

}

}

·        Обработка нажатия кнопки "Получить отчет"

public void getReport(ActionEvent actionEvent) {= field_lang.getText();();= DataChecker.validData();(errors.isEmpty()) {userList = new UserList(new ArrayList<>(userObservableList));taskList = new TaskList(new ArrayList<>(taskObservableList));queryDataListBuilder = new QueryDataListBuilder(userList, taskList);resultMapper = new ResultMapper(queryDataListBuilder);reportBuilder = new ReportBuilder(resultMapper, taskList);resultFile = reportBuilder.reportBuild();(Main.getFileResult() == null) {.showAndSave(resultFile);

} else {.saveHtmlDocument(resultFile);

}

} else {.createErrorsMS();

}

}

·        Класс построения отчетаclass ReportBuilder {static final String TEMPLATE = "row";static final String POINTS = "points";static final String LEVEL = "level";static final String NAME = "name";static final String SOLVE_CLASS = "solve";static final String OLD_SOLVE_CLASS = "oldsolve";static final String NOT_SOLVE_CLASS = "notsolve";static final String PLUS = "+";static final String MINUS = "-";static final String POINTS_HEAD = "pointsHead";Element rowTemplate;Element headerTemplate;Element tdTemplate;Document table;String lastIdRow = "header";String lastIdColumn = "fio";HashMap<String, HashMap<String, List<ResultItem"> resultMap = new HashMap<>();StoreBuilder sb;ResultMapper resultMapper;(ResultMapper resultMapper, TaskList taskList) {.resultMapper = resultMapper;= resultMapper.getResultMap();= new StoreBuilder(resultMapper);html = Template.template;= Jsoup.parse(html);(sort.equals(SORT_BY_SOLVE)) {.getElementById(POINTS_HEAD).remove();

}();();(taskList);(taskList);();

}void createReport() {<String> names = sb.getStoreList();status, style;(String name : names) {<String> taskNums = resultMap.get(name).keySet();row = createNewResultRow(name);.getElementById(NAME).html(name);.getElementById(LEVEL).html(getPlace(name));(sort.equals(SORT_BY_POINTS)) {.getElementById(POINTS).html(getPoints(name));

}(String task : taskNums) {<ResultItem> resultItems = resultMap.get(name).get(task);= isSolveOrOldSolve(name, task) ? PLUS : MINUS;(status.equals(PLUS)) {= (sb.isSolve(name, task)) ? SOLVE_CLASS : OLD_SOLVE_CLASS;

} else {= NOT_SOLVE_CLASS;

}.getElementById(task).addClass(style);.getElementById(task).html(resultMapper.getFio_task_tryCount_map().get(name).get(task) + status);

}.getElementById(lastIdRow).after(row.toString());= name;

}

}String getPoints(String name) {(sb.getFio_solvePoints_map().get(name) != null) ? String.valueOf(sb.getFio_solvePoints_map().get(name)) :

"0";

}String getPlace(String name) {String.valueOf(sb.getFio_place().get(name));

}boolean isSolveOrOldSolve(String name, String task) {sb.isSolve(name, task) || sb.isOldSolve(name, task);

}void setTaskColumns(TaskList taskList) {[] taskNum = taskList.getAllTasks();newTh;(String aTaskNum : taskNum) {= createNewTh(aTaskNum);.getElementById(lastIdColumn).after(newTh.toString());= aTaskNum;

}

}reportBuild() {table.toString();

}Element createNewTemplateTd(String id) {newTd = tdTemplate.clone();.attr("id", id);newTd;

}void setRowTemplate(TaskList taskList) {= table.getElementById(TEMPLATE);.getElementById(TEMPLATE).remove();(sort.equals(SORT_BY_SOLVE)) {.getElementById(POINTS).remove();

Источник: https://www.bibliofond.ru/detail.aspx?id=896880