DIPLOM (1204343), страница 5
Текст из файла (страница 5)
3.2 Разработка модуля
Разработанный программный модуль содержит несколько диалоговых окон. Окно авторизации администратора содержит два поля, Имя пользователя и Пароль (рисунок 6). В данной программе может быть зарегистрировано неограниченное количество пользователей с правами администратора.
class AdminLoginFormT : public QWidget
{
Q_OBJECT
QLineEdit *user_name_form = new QLineEdit(ADMIN_NAME);
QLineEdit *user_pass_form = new QLineEdit(ADMIN_PASS);
QLabel *error_label = new QLabel(trUtf8(" "));
public:
AdminLoginFormT(QWidget* p)
: QWidget(p)
{
QPushButton *submit_button = new QPushButton(trUtf8("Войти"));
QLabel *pass_label = new QLabel(trUtf8("Пароль:"));
QLabel *user_label = new QLabel(trUtf8("Имя пользователя:"));
// submit_button->setMaximumWidth(150);
user_name_form->setMaximumWidth(150);
user_pass_form->setMaximumWidth(150);
Рисунок 6 – Окно авторизации администратора
Каждый администратор обладает уникальным именем пользователя и паролем. Эти данные можно изменить только в конструкторе [6].
В режиме администрирования, пользователь может создавать тесты с неограниченным количеством вопросов, сами вопросы могут быть с неограниченным количеством ответов, удалять тесты, устанавливать необходимое время на тестирование (рисунок 8), администратор запускает прохождение теста (рисунок 7) [5].
class AdminQuestionEditWgt : public QGroupBox
{
Q_OBJECT
QGridLayout *lay = new QGridLayout(0);
QPushButton *addButton = new QPushButton(trUtf8("Добавить вопрос"), this);
QPushButton *addTestButton = new QPushButton(trUtf8("Добавить тест"), this);
QPushButton *delTestButton = new QPushButton(trUtf8("Удалить тест"), this);
QPushButton *startTestButton = new QPushButton(trUtf8("Начать тестирование"), this);
QComboBox* currentTestListWgt = new QComboBox(this);
std::vector<AdminQuestionWgt*> wgtVec;
QLabel* statsWgt = new QLabel(this);
void repaint()
{
int insertWgtIndex = 3;
for (auto it : wgtVec)
delete it;
wgtVec.clear();
statsWgt->setText(trUtf8("Всего вопросов: %1").arg(qList.size()));
for (int i=0; i<(int)qList.size(); i++) {
auto* p = new AdminQuestionWgt(this, qList[i], i+1);
wgtVec.push_back(p);
lay->addWidget(p, insertWgtIndex++, 0, 1, 3);
connect(p, AdminQuestionWgt::deleted, this, deleteQuestion);
connect(p, AdminQuestionWgt::changed, this, editQuestion);
}
}
Рисунок 7 – Диалоговое окно администратора
class TestSettings {
static auto getFileAddr(const QString &tName) {
return QString(QUESTIONS_DIR) + tName + "/settings.ini";
}
bool set(const QString &tName, auto &&key, auto &&value)
{
QSettings sets(getFileAddr(tName), QSettings::IniFormat);
sets.setValue(key, value);
return sets.status() == QSettings::NoError;
}
public:
auto getTestTime(const QString &tName) const {
QSettings sets(getFileAddr(tName), QSettings::IniFormat);
return sets.value("test_time", 60*15).toUInt();
}
auto setTestTime(const QString &tName, uint value) {
return set(tName, "test_time", value);
}
};
Рисунок 8 – Окно создания нового теста
В окне добавления вопроса администратор записывает вопрос, который в дальнейшем реалтизована возможность редактировать его в любой момент, а также заполняет варианты ответов, и указывает правильный (рисунок 9).
class QuestionFileT
{
QString question;
QString correct_answer;
std::vector<QString> answers_list;
public:
QuestionFileT() = default;
~QuestionFileT() = default;
QuestionFileT& operator=(const QuestionFileT&) = default;
QuestionFileT& operator=(QuestionFileT&&) = default;
QuestionFileT(const QuestionFileT&) = default;
QuestionFileT(QuestionFileT&&) = default;
QuestionFileT(auto&& question1, auto&& correct_answer, auto&& answers_list)
: question(std::forward<decltype(question1)>(question1))
, correct_answer(std::forward<decltype(correct_answer)>(correct_answer))
, answers_list(std::forward<decltype(answers_list)>(answers_list))
{
}
const auto& getQuestion() const { return question; }
const auto& getAnswer() const { return correct_answer; }
const auto& getAnswerVariants() const { return answers_list; }
bool operator == (const QuestionFileT& rhs) const
{
return question==rhs.question;
}
operator void*() const {
return (void*)(question.size()
&& correct_answer.size()
&& answers_list_is_correct()
? 1 : 0);
}
void setAnswer(auto&& str) { correct_answer = str; }
void setQuestion(auto&& str) { question = str; }
private:
bool answers_list_is_correct() const
{
for (const auto& it : answers_list)
if (!it.size())
return false;
return true;
}
};
Рисунок 9 – Окно создания нового вопроса
После начала тестирования пользователь, который будет проходить тест, должен ввести свои данные (рисунок 10), которые по окончанию тестирования будут сохранены в ведомости, которая хранится в базе данных (рисунок 11) [22].
{
Q_OBJECT
QLineEdit* yourNameEdit = new QLineEdit(this);
QPushButton* startTestButton = new QPushButton(trUtf8("Начать тестирование"), this);
public:
UserLoginForm(QWidget *parent)
: QWidget(parent)
{
Рисунок 10 – Окно авторизации пользователя
auto addData(const TestResult &data)
{
QSqlQuery query(db);
query.prepare("INSERT INTO `test_results`"
" (`test_name`, `user_name`, `total_question`, `skip_question`, `true_answers`, `false_answers`, `testing_time`, `elapsed_test_time`)"
" VALUES (:test_name, :user_name, :total_question, :skip_question, :true_answers, :false_answers, :testing_time, :elapsed_test_time)");
query.bindValue(":test_name", data.test_name.toStdString().c_str());
query.bindValue(":user_name", data.user_name.toStdString().c_str());
query.bindValue(":total_question", data.total_question);
query.bindValue(":skip_question", data.skip_question);
query.bindValue(":true_answers", data.true_answers);
query.bindValue(":false_answers", data.false_answers);
query.bindValue(":testing_time", data.testing_time);
query.bindValue(":elapsed_test_time", data.elapsed_test_time);
return query.exec();
}
auto& getDBHandle() {
return db;
Рисунок 11 – Ведомость
Данные хранятся в базе данных, которая поддерживает язык SQL. Ведомость содержит информацию, о тестируемом, наименовании теста который он проходил, количество вопросов, содержащихся в тесте, количество правильно отвеченных, пропущенных и неправильно отвеченных вопросах, а так же, дату тестирования, время и прохождения, и результаты тестирования в процентах.
После прохождения авторизации, тестируемый за отведенное время отвечает на вопросы (рисунок 12).
this->setTitle(QString(trUtf8("Вопрос №%1").arg(q_counter)));
int index = 0;
auto l = new QLabel(q.getQuestion());
l->setWordWrap(true);
grid->addWidget(l, index++, 0, 1, 2);
for (const auto& it : q.getAnswerVariants()) {
auto wgt = new QRadioButton(it, this);
variants.push_back(wgt);
grid->addWidget(wgt, index++, 0, 1, 2);
}
variants[0]->setChecked(true);
grid->addWidget(skip_button, index, 0);
grid->addWidget(accept_button, index++, 1);
connect(skip_button, QPushButton::clicked, this, skip_slot);
connect(accept_button, QPushButton::clicked, this, accept_slot);
Рисунок 12 – Окно тестирования
После прохождения теста, создается протокол с данными о тестировании (рисунок 13).
QLabel* uName = new QLabel(QString(trUtf8("Тестируемый: %1").arg(testResult.user_name)));
QLabel* elapTime = new QLabel(QString(trUtf8("Время прохождения теста: %1").arg(string_time(testResult.elapsed_test_time))));
QLabel* total_l = new QLabel(QString(trUtf8("Вопросов всего: %1").arg(testResult.total_question)));
QLabel* correct = new QLabel(QString(trUtf8("Правильных ответов: %1").arg(testResult.true_answers)));
QLabel* unCorrect = new QLabel(QString(trUtf8("Неправильных ответов: %1").arg(testResult.false_answers)));
QLabel* skipQ = new QLabel(QString(trUtf8("Пропущено вопросов: %1").arg(testResult.skip_question)));
QLabel* result_l = new QLabel(QString(trUtf8("Ваш результат: %1%").arg(userResult(testResult.true_answers, testResult.total_question))));
grid->addWidget(uName, 0, 0);
grid->addWidget(total_l, 1, 0);
grid->addWidget(correct, 2, 0);
grid->addWidget(unCorrect, 3, 0);
grid->addWidget(skipQ, 4, 0);
grid->addWidget(result_l, 5, 0);
grid->addWidget(elapTime, 6, 0);
Рисунок 13 – Окно с результатами тестирования
В ходе выпускной квалификационной работы был разработан программный модуль для тестирования сотрудников КГБУЗ «Спасская СП», удовлетворяющий всем требованиям данной организации. Реализованы все функции, которые были запланированы:
‒ применение форматирования ко всем вопросам;
‒ запуск теста из конструктора;
‒ запуск теста через ярлык;
‒ установка пароля для теста;
‒ авторизация пользователей перед началом тестирования;
‒ ввод ограничений по времени для прохождения теста;
‒ запрет на преждевременное закрытие теста во время его прохождения;
‒ генерирование вопросов в случайном порядке;
‒ генерирование ответов в случайном порядке;
‒ возврат к предыдущему вопросу при прохождении тестирования;
‒ отображение результатов тестирования в оценках;
‒ построение отчетов по результатам тестирования.
4 Технико-экономическое обоснование
Сегодняшний рынок программного обеспечения предлагает довольно широкий ассортимент программных комплексов и тестирующих программ, позволяющих вести контроль знаний сотрудников в различных областях.
Использование разработанного модуля является целесообразным, так как не требует дорогостоящих персональных компьютеров и особой квалификации как администраторов данного тестирующего модуля, так и самих тестируемых, а также уменьшает временные затраты сотрудников на проверку, и создание тестов, снижает к нулю вероятность допуска ошибки при проверке результатов тестирования, снижает затраты на распечатку бумажных тестов [15].
Пользователями данного программного модуля будут сотрудники отдела кадров, бухгалтерский отдел, а также непосредственно сами медицинские работники. Применение данного модуля значительно облегчит их труд и сократит затраты на проведение контроля знаний как уже работающего персонала, так и вновь прешедшего [17].
Для оценки конкурентоспособности разрабатываемого продукта необходимо провести анализ и сравнение с выбранным аналогом по функциональному назначению, основным техническим и эксплуатационным параметрам, областям применения. Подобный анализ осуществляется с помощью оценки эксплуатационно-технического уровня разрабатываемого продукта.
В пункте 1.4 приведен сравнительный анализ твух тестирующих систем. Разработанный программый модуль тестирования, обладает большинством функций рассмотренных тестирующих систем, а также включает уникальные. Главное достоинство относительно расммотренных программ, это бесплатная разработка тестирующего модуля.
Эксплуатационно-технический уровень (ЭТУ) разрабатываемого продукта – это обобщенная характеристика его эксплуатационных свойств, возможностей, степени новизны, являющихся основой качества продукта. Для определения ЭТУ продукта можно использовать индекс эксплуатационно-технического уровня JЭТУ, который рассчитывается как сумма частных индексов, куда входят показатели качества программного продукта. Для учета значимости отдельных параметров применяется балльно-индексный метод.
Тогда
| |
где JЭТУ – комплексный показатель качества продукта по группе показателей;
n – число рассматриваемых показателей;
Вj – коэффициент весомости j-го показателя в долях единицы, назначаемый в соответствии с потребностями организации-заказчика программного продукта;
,














