This commit is contained in:
3eef8a28f26fb2bcc514e6f1938929a1f931762 2023-02-04 15:06:20 -05:00
parent 7ad5f2ff55
commit d6dc6b080c

View file

@ -5,19 +5,13 @@
#include<filesystem> #include<filesystem>
#include<dist/jsoncpp.cpp> #include<dist/jsoncpp.cpp>
struct course_sections_data_t {
int credMin = Json::Value::maxInt;
int credMax = 0;
int seatsTaken = 0;
int capacity = 0;
int remaining = 0;
};
namespace fs = std::filesystem; namespace fs = std::filesystem;
void handle_term(const fs::directory_entry&,Json::Value&); void handle_term(const fs::directory_entry&,Json::Value&);
void handle_prefix(const Json::Value&,const std::string&,Json::Value&);
void handle_course(const Json::Value&,const std::string&,Json::Value&); void handle_course(const Json::Value&,const std::string&,Json::Value&);
void handle_attribute(Json::Value&,const std::string&); void handle_attribute(const std::string&,Json::Value&);
course_sections_data_t handle_sections(const Json::Value&); void handle_attributes(const Json::Value&,Json::Value&);
void handle_sections(const Json::Value&,Json::Value&);
int main(const int argc,const char** argv) { int main(const int argc,const char** argv) {
if(argc < 2) { if(argc < 2) {
@ -69,88 +63,93 @@ void handle_term(const fs::directory_entry& term_entry,
#ifdef DEBUG #ifdef DEBUG
std::cerr << '\t' << courses_filename << std::endl; std::cerr << '\t' << courses_filename << std::endl;
std::cerr << '\t' << prereqs_filename << std::endl; std::cerr << '\t' << prereqs_filename << std::endl;
std::cerr << "Processing term " << term << "..." << std::endl;
#endif #endif
std::cerr << "Processing term " << term << "..." << std::endl;
terms_offered["all_terms"].append(term); terms_offered["all_terms"].append(term);
Json::Value courses; Json::Value courses;
courses_file >> courses; courses_file >> courses;
for(auto prefix : courses) { for(auto prefix : courses) {
handle_prefix(prefix,term,terms_offered);
}
}
void handle_prefix(const Json::Value& prefix,const std::string& term,Json::Value& terms_offered) {
#ifdef DEBUG #ifdef DEBUG
std::cerr << "\tProcessing prefix " std::cerr << "\tProcessing prefix "
<< prefix["code"] << prefix["code"]
<< " - " << " - "
<< prefix["name"] << prefix["name"]
<< "..." << "..."
<< std::endl; << std::endl;
#endif #endif
for(auto course : prefix["courses"]) { for(auto course : prefix["courses"]) {
handle_course(course,term,terms_offered); handle_course(course,term,terms_offered);
}
} }
} }
void handle_course(const Json::Value& course,const std::string& term,Json::Value& terms_offered) { void handle_course(const Json::Value& course,const std::string& term,Json::Value& terms_offered) {
const auto course_code = course["id"].asString(); const auto course_code = course["id"].asString();
auto& course_term = terms_offered[course_code][term];
course_term["title"] = course["title"];
Json::Value sections = course["sections"]; Json::Value sections = course["sections"];
course_sections_data_t course_sections_data = handle_sections(sections); auto& course_term = terms_offered[course_code][term];
course_term["title"] = course["title"];
course_term["credits"]["min"] = course_sections_data.credMin;
course_term["credits"]["max"] = course_sections_data.credMax; handle_sections(sections,course_term);
course_term["seats"]["taken"] = course_sections_data.seatsTaken; handle_attributes(course["sections"][0],course_term);
course_term["seats"]["capacity"] = course_sections_data.capacity; }
course_term["seats"]["remaining"] = course_sections_data.remaining;
void handle_sections(const Json::Value& sections,Json::Value& course_term) {
int credMin = Json::Value::maxInt, credMax = 0;
int seatsTaken = 0, capacity = 0, remaining = 0;
for(auto section : sections) {
// Get min/max credits *of all sections*
// (RCOS looking at you)
credMin = std::min(credMin,section["credMin"].asInt());
credMax = std::max(credMax,section["credMax"].asInt());
// Add seating data of all sections together.
// remaining might get clobbered by some sections
// having negative seats, but this probably won't
// be too much of an issue
seatsTaken += section["act"].asInt();
capacity += section["cap"].asInt();
remaining += section["rem"].asInt();
}
course_term["credits"]["min"] = credMin;
course_term["credits"]["max"] = credMax;
course_term["seats"]["taken"] = seatsTaken;
course_term["seats"]["capacity"] = capacity;
course_term["seats"]["remaining"] = remaining;
}
void handle_attributes(const Json::Value& section,Json::Value& course_term) {
// Need to do this because for some reason attributes are by // Need to do this because for some reason attributes are by
// section instead of by course // section instead of by course
const auto section = course["sections"][0];
// This mess is basically C++'s string split but not using
// as much memory as an actual string split
const auto delim = std::regex(" and |, "); const auto delim = std::regex(" and |, ");
const auto attributes_str = section["attribute"].asString(); const auto attributes_str = section["attribute"].asString();
const auto end_itr = std::sregex_token_iterator(); const auto end_itr = std::sregex_token_iterator();
auto attributes_itr = std::sregex_token_iterator( auto attributes_itr = std::sregex_token_iterator(
attributes_str.begin(), attributes_str.begin(),
attributes_str.end(), attributes_str.end(),
delim, delim,
-1 -1
); );
// Makes the JSON list of attributes
while(attributes_itr != end_itr while(attributes_itr != end_itr
&& !attributes_itr->str().empty()) { && !attributes_itr->str().empty()) {
handle_attribute(course_term,attributes_itr->str()); handle_attribute(attributes_itr->str(),course_term);
attributes_itr++; attributes_itr++;
} }
} }
course_sections_data_t handle_sections(const Json::Value& sections) { void handle_attribute(const std::string& attribute,Json::Value& course_term) {
course_sections_data_t csd;
//csd.credMin = Json::Value::maxInt;
//csd.credMax = 0;
//csd.seatsTaken = 0, capacity = 0, remaining = 0;
for(auto section : sections) {
// Get min/max credits *of all sections*
// (RCOS looking at you)
csd.credMin = std::min(csd.credMin,section["credMin"].asInt());
csd.credMax = std::max(csd.credMax,section["credMax"].asInt());
// Add seating data of all sections together.
// remaining might get clobbered by some sections
// having negative seats, but this probably won't
// be too much of an issue
csd.seatsTaken += section["act"].asInt();
csd.capacity += section["cap"].asInt();
csd.remaining += section["rem"].asInt();
}
return csd;
}
void handle_attribute(Json::Value& course_term,const std::string& attribute) {
std::string attr; std::string attr;
if(attribute == "Communication Intensive") { if(attribute == "Communication Intensive") {
attr = "[CI]"; attr = "[CI]";