datahandler.cpp (5902B)
1 #include "datahandler.hpp" 2 3 DataHandler::DataHandler() 4 :misscount(0), errcount(0) {} 5 6 DataHandler::~DataHandler() 7 { 8 dealloc<Course>(courses); 9 dealloc<Student>(studs); 10 if (!grds.empty()) grds.clear(); 11 if (!data.empty()) data.clear(); 12 if (!eqvs.empty()) eqvs.clear(); 13 if (!errs.empty()) errs.clear(); 14 if (!missing.empty()) missing.clear(); 15 } 16 17 void 18 DataHandler::load_grades() 19 { 20 std::ifstream f; 21 f.exceptions(std::ifstream::badbit); 22 try 23 { 24 f.open(datapath); 25 if (f.is_open()) 26 { 27 std::printf("Importing data from \'%s\'\n\n", datapath); 28 std::printf("Making data structures and analyzing data.\n"); 29 lab::xstring skip; 30 lab::getline(f, skip); 31 32 lab::xstring id, code, grade; 33 lab::getline(f, id, ';'); 34 lab::getline(f, code, ';'); 35 lab::getline(f, grade); 36 37 std::map<lab::xstring, Student *>::const_iterator its = studs.find(id); 38 std::map<lab::xstring, Course *>::const_iterator itc = courses.find(code); 39 if (its != studs.end() && itc != courses.end()) 40 grds.insert(std::make_pair(courses[code], std::atof(grade.cstr()))); 41 42 while (f.good()) 43 { 44 lab::xstring currid = id; 45 while (currid == id) 46 { 47 lab::getline(f, id, ';'); 48 lab::getline(f, code, ';'); 49 lab::getline(f, grade); 50 if (f.eof()) break; 51 analyze(currid, id, code, std::atof(grade.cstr())); 52 } 53 } 54 } 55 f.close(); 56 } 57 catch (const std::ifstream::failure& e) 58 { 59 errlog.write(ErrLog::ErrType::RUNTIME_ERR, err_read(datapath)); 60 throw std::runtime_error(err_read(datapath).cstr()); 61 } 62 } 63 64 void 65 DataHandler::analyze( 66 const lab::xstring& currid, 67 lab::xstring& id, 68 lab::xstring& code, 69 float grade) 70 { 71 std::map<lab::xstring, Student *>::const_iterator its = studs.find(id); 72 std::map<lab::xstring, Course *>::const_iterator itc = courses.find(code); 73 if (its != studs.end() && itc != courses.end()) 74 { 75 if (currid != id) 76 { 77 data.insert(std::make_pair(studs[currid], grds)); 78 grds.clear(); 79 grds.insert(std::make_pair(courses[code], grade)); 80 return; 81 } 82 grds.insert(std::make_pair(courses[code], grade)); 83 } 84 else if (its == studs.end() && 85 std::find(errs.begin(), errs.end(), id) == errs.end()) 86 { 87 errs.push_back(id); 88 errlog.write(ErrLog::ErrType::STUDENT_MISSING, id); 89 errcount++; 90 } 91 else if (itc == courses.end() && 92 std::find(errs.begin(), errs.end(), code) == errs.end()) 93 { 94 errs.push_back(code); 95 errlog.write(ErrLog::ErrType::COURSE_MISSING, code); 96 errcount++; 97 } 98 99 if (its != studs.end() && itc != courses.end()) 100 { 101 miss(id, code, grade); 102 diffr(id, code, grade); 103 } 104 } 105 106 void 107 DataHandler::miss(lab::xstring id, lab::xstring code, float grade) 108 { 109 if (courses[code]->four_year) 110 { 111 std::map<lab::xstring, lab::xstring>::const_iterator it = eqvs.find(code); 112 if (it != eqvs.end()) 113 { 114 bool found = false; 115 for (const auto& grd : grds) 116 if (grd.first->code == eqvs[code]) 117 found = true; 118 if (!found) 119 { 120 missing.push_back(id + ";" + 121 studs[id]->lname + ";" + 122 studs[id]->fname + ";" + 123 courses[eqvs[code]]->code + ";" + 124 courses[eqvs[code]]->name + ";" + 125 code + ";" + 126 courses[code]->name + ";" + 127 lab::to_xstr<float>("%.1f", grade)); 128 misscount++; 129 } 130 } 131 } 132 } 133 134 void 135 DataHandler::diffr(lab::xstring id, lab::xstring code, float grade) 136 { 137 std::map<Course *, float>::const_iterator it = grds.find(courses[code]); 138 if (it != grds.end() && it->second != grade) 139 { 140 errlog.write(ErrLog::ErrType::DIFFERENT_GRADES, 141 lab::xstring(id + " in " + code + ": " + 142 lab::to_xstr<float>("%.1f", it->second) + " | " + 143 lab::to_xstr<float>("%.1f", grade))); 144 errcount++; 145 } 146 } 147 148 void 149 DataHandler::make_report() const 150 { 151 std::ofstream f; 152 f.exceptions(std::ofstream::failbit | std::ofstream::badbit); 153 try 154 { 155 f.open(reppath); 156 if (f.is_open()) 157 { 158 std::printf("Making report.\n"); 159 f << "ID;Last name;First name;New course code;New course name;" << 160 "Old course code;Old course name;Grade" << std::endl; 161 for (const auto& m : missing) f << m << std::endl; 162 f.close(); 163 } 164 } 165 catch (const std::ofstream::failure& e) 166 { 167 errlog.write(ErrLog::ErrType::RUNTIME_ERR, err_write(reppath)); 168 } 169 } 170 171 172 void 173 DataHandler::summary() const 174 { 175 int datacount = 0; 176 for (const auto& dat : data) 177 datacount += dat.second.size(); 178 179 std::printf("\nStudents: %ld\n", studs.size()); 180 std::printf("Courses: %ld\n", courses.size()); 181 std::printf("Equivalences: %ld\n", eqvs.size()); 182 std::printf("Total grades stored: %d\n", datacount); 183 std::printf("Grades missing: %d\n", misscount); 184 std::printf("Errors: %d\n", errcount); 185 std::printf("\nThank you :)\n"); 186 } 187 188 const lab::xstring 189 DataHandler::err_read(const char *fpath) const 190 { 191 return lab::xstring("Error reading file \'\'.").insert(fpath, 20); 192 } 193 194 const lab::xstring 195 DataHandler::err_write(const char *fpath) const 196 { 197 return lab::xstring("Error writing to file \'\'.").insert(fpath, 23); 198 }