readtest/source/app.d

219 lines
5.9 KiB
D
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import singlog;
import core.stdc.stdlib : exit, EXIT_SUCCESS, EXIT_FAILURE;
import std.stdio, std.conv, std.path, std.file, std.format, std.regex, std.array, std.algorithm;
import source.database;
import source.sql;
enum {
GROUP_THEME = 2,
GROUP_THEME_TEXT = 5,
GROUP_QUESTION = 7,
GROUP_QUESTION_TEXT = 10,
GROUP_ANSWER = 12,
GROUP_ANSWER_TEXT = 15,
GROUP_ANSWER_RIGHT = 17,
GROUP_ANSWER_RIGHT_TEXT = 20,
}
int main(string[] args)
{
log.level(log.level.debugging)
.output(log.output.stdout.stderr)
.color(true);
string testFilePath;
string databaseFile;
if (args.length != 3) {
log.e("Не было передано необходимое количество параметров для запуска программы");
return EXIT_FAILURE;
}
databaseFile = args[1];
testFilePath = args[2];
const string pattern = "^((( |\\t)*\\#( |\\t)*)(.*[^\\s]))|((( |\\t)*\\?( |\\t)*)(.*[^\\s]))"
~ "|((( |\\t)*-( |\\t)*)(.*[^\\s]))|((( |\\t)*\\+( |\\t)*)(.*[^\\s]))$";
File testFile;
try {
testFile = File(testFilePath, "r");
} catch (Exception e) {
log.w("Unable to open the test file " ~ testFilePath);
log.e(e);
return EXIT_FAILURE;
}
dbliteConnect(databaseFile);
auto regular = regex(pattern, "m");
struct Answer {
int number;
string text;
bool truth;
bool addToDB(int question_id) {
int id = sqlAddNewAnswer(question_id, this.number, this.text, this.truth);
if (!id)
return false;
return true;
}
}
struct Question {
int number;
string text;
Answer[int] answers;
ulong count() {
return answers.length;
}
bool isValid() {
return answers.length > 1;
}
bool addToDB(int topic_id) {
int id = sqlAddNewQuestion(topic_id, this.number, this.text);
if (!id)
return false;
foreach (answer; answers.byKeyValue.array.sort!((a, b) => a.key < b.key)) {
if (!answer.value.addToDB(id))
return false;
}
return true;
}
}
struct Theme {
string text;
Question[int] questions;
ulong count() {
return questions.length;
}
bool isValid() {
return questions.length > 1;
}
bool addToDB() {
if (!check())
return false;
int id = sqlAddNewTheme(this.text);
if (!id)
return false;
foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) {
if (!question.value.addToDB(id))
return false;
}
return true;
}
void print() {
writeln("Количество вопросов: %s".format(this.count()));
foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) {
writeln("\tВопрос №%d: %s".format(question.key, question.value.text));
writeln("\tКоличество ответов: %d".format(question.value.count()));
foreach (answer; question.value.answers.byKeyValue.array.sort!((a, b) => a.key < b.key)) {
writeln("\t\tОтвет №%d: %s".format(answer.key, answer.value.text));
}
}
}
bool check() {
bool error = false;
if (!this.isValid()) {
writeln("Недостаточное количество вопросов: %d".format(this.count()));
error = true;
}
if (!error) {
foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) {
if (!question.value.isValid()) {
writeln("Вопрос №%d \"%s\" содержит недостаточное количество ответов: %d".format(
question.key, question.value.text, question.value.count()
));
error = true;
}
int truth;
foreach (answer; question.value.answers) {
if (answer.truth)
++truth;
}
if (truth > 1) {
writeln("Вопрос №%d \"%s\" содержит более одного правильного ответа".format(
question.key, question.value.text
));
error = true;
}
}
}
return !error;
}
}
Theme theme;
int numQuestion;
int numAnswer;
while (!testFile.eof())
{
string line = testFile.readln();
auto match = matchFirst(line, regular);
if (match.length == 0)
continue;
if (match[GROUP_THEME].length)
{
theme.text = match[GROUP_THEME_TEXT];
continue;
}
if (match[GROUP_QUESTION].length)
{
numAnswer = 0;
theme.questions[++numQuestion] = Question(numQuestion, match[GROUP_QUESTION_TEXT]);
continue;
}
if (match[GROUP_ANSWER].length)
{
theme.questions[numQuestion].answers[++numAnswer] = Answer(numAnswer, match[GROUP_ANSWER_TEXT], false);
continue;
}
if (match[GROUP_ANSWER_RIGHT].length)
{
theme.questions[numQuestion].answers[++numAnswer] = Answer(numAnswer, match[GROUP_ANSWER_RIGHT_TEXT], true);
continue;
}
}
// theme.print();
// theme.check();
theme.addToDB();
return EXIT_SUCCESS;
}