Skip to content
This repository has been archived by the owner on Nov 6, 2023. It is now read-only.

students_classes.csv #17

Merged
merged 7 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/c-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,3 @@ jobs:
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest -C ${{env.BUILD_TYPE}}


32 changes: 25 additions & 7 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,32 @@
#include <string>

int main(int argc, char** argv) {
std::ifstream file = std::ifstream("schedule/classes_per_uc.csv");
std::string contents;
std::ostringstream sstr;
sstr << file.rdbuf();
contents = sstr.str();
AppCPU cpu = AppCPU(contents);
// AppClassesPerUC
std::ifstream file1 = std::ifstream("schedule/classes_per_uc.csv");
std::string contents1;
std::ostringstream sstr1;
sstr1 << file1.rdbuf();
contents1 = sstr1.str();
AppCPU cpu = AppCPU(contents1);
cpu.display();

//std::cout << "Hello, World!" << std::endl;
// AppStudentsClasses
std::ifstream file2 = std::ifstream("schedule/students_classes.csv");
std::string contents2;
std::ostringstream sstr2;
sstr2 << file2.rdbuf();
contents2 = sstr2.str();
AppStudentsClasses sc(contents2);
sc.display();

// AppClass
std::ifstream file3 = std::ifstream("schedule/classes.csv");
std::string contents3;
std::ostringstream sstr3;
sstr3 << file3.rdbuf();
contents3 = sstr3.str();
AppClass ac(contents3);
ac.display();

return 0;
}
140 changes: 140 additions & 0 deletions src/appStudentsClasses.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include "appStudentsClasses.hpp"
#include "studentsClasses.hpp"
#include "Utils.hpp"
#include <sstream>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>

// Constructor
AppStudentsClasses::AppStudentsClasses(std::string csv) {
std::stringstream s(csv);
std::string line;
this->entries = std::vector<StudentsClasses>();
getline(s,line,'\n');
std::vector<std::string> bufs;
parse_csv_line(line,bufs);
this->student_code_cath_name = bufs[0];
this->student_name_cath_name = bufs[1];
this->uc_code_cath_name = bufs[2];
this->class_code_cath_name = bufs[3];
line.clear();
while (std::getline(s,line,'\n')) {
this->entries.push_back(StudentsClasses(line));
}
}

// Methods
void AppStudentsClasses::sort_by(const std::string& category) {
if (category == this->student_code_cath_name) {
std::stable_sort(this->entries.begin(), this->entries.end(),
[](const StudentsClasses& a, const StudentsClasses& b) {return a.get_student_code() < b.get_student_code();});

} else if (category == this->student_name_cath_name) {
std::stable_sort(this->entries.begin(), this->entries.end(),
[](const StudentsClasses& a, const StudentsClasses& b) {return a.get_student_name() < b.get_student_name();});

} else if (category == this->uc_code_cath_name) {
std::stable_sort(this->entries.begin(), this->entries.end(),
[](const StudentsClasses& a, const StudentsClasses& b) {return a.get_uc_code() < b.get_uc_code();});

} else if (category == this->class_code_cath_name) {
std::stable_sort(this->entries.begin(), this->entries.end(),
[](const StudentsClasses& a, const StudentsClasses& b) {return a.get_class_code() < b.get_class_code();});

} else {
std::cerr << "Error: invalid category" << '\n';
std::exit(1);
}
}

std::vector<StudentsClasses>::iterator AppStudentsClasses::search_by_uc(uint16_t uc_code) {
sort_by(uc_code_cath_name);
auto ret = entries.end();
size_t mid = entries.size() / 2;

while (true) { // Binary search
if (mid == entries.size()) {
return ret;
} else if (entries[mid].get_uc_code() == uc_code) {
ret = entries.begin() + mid;
break;
} else if (entries[mid].get_uc_code() > uc_code) {
mid = mid / 2;
} else {
mid = mid + mid / 2;
}
}

while (true) {
if ((ret - 1)->get_uc_code() != uc_code) {
return ret;
} else --ret;
}
}

std::vector<StudentsClasses>::iterator AppStudentsClasses::search_by_student(uint32_t student_code) {
sort_by(student_code_cath_name);
auto ret = entries.end();
size_t mid = entries.size() / 2;

while (true) { // Binary search
if (mid == entries.size()) {
return ret;
} else if (entries[mid].get_student_code() == student_code) {
ret = entries.begin() + mid;
break;
} else if (entries[mid].get_student_code() > student_code) {
mid = mid / 2;
} else {
mid = mid + mid / 2;
}
}

while (true) {
if ((ret - 1)->get_student_code() != student_code) {
return ret;
} else --ret;
}
}

std::vector<StudentsClasses>::iterator AppStudentsClasses::search_by_class(uint16_t class_code) {
sort_by(class_code_cath_name);
auto ret = entries.end();
size_t mid = entries.size() / 2;

while (true) { // Binary search
if (mid == entries.size()) {
return ret;
} else if (entries[mid].get_class_code() == class_code) {
ret = entries.begin() + mid;
break;
} else if (entries[mid].get_class_code() > class_code) {
mid = mid / 2;
} else {
mid = mid + mid / 2;
}
}

while (true) {
if ((ret - 1)->get_class_code() != class_code) {
return ret;
} else --ret;
}
}


// Degub
void AppStudentsClasses::display() const {
std::cout << this->student_code_cath_name << ','
<< this->student_name_cath_name << ','
<< this->uc_code_cath_name << ','
<< this->class_code_cath_name << '\n';
for (const auto& e : this->entries) {
e.display();
}
}



25 changes: 25 additions & 0 deletions src/appStudentsClasses.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "studentsClasses.hpp"
#include <string>
#include <vector>

class AppStudentsClasses {
private:
std::string student_code_cath_name;
std::string student_name_cath_name;
std::string uc_code_cath_name;
std::string class_code_cath_name;
std::vector<StudentsClasses> entries;

public:
// Constructor
AppStudentsClasses(std::string csv);

// Methods
void sort_by(const std::string& category);
std::vector<StudentsClasses>::iterator search_by_student(uint32_t student_code);
std::vector<StudentsClasses>::iterator search_by_uc(uint16_t uc_code);
std::vector<StudentsClasses>::iterator search_by_class(uint16_t class_code);

// Debug
void display() const;
};
132 changes: 132 additions & 0 deletions src/studentsClasses.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include "studentsClasses.hpp"
#include "Utils.hpp"
#include <string>
#include <cstdint>
#include <vector>
#include <iostream>
#include <iomanip>
#include <sstream>

// Constructor
StudentsClasses::StudentsClasses(std::string& line) {
std::vector<std::string> linebuf;
parse_csv_line(line, linebuf);
student_code_ = parse_student_code(linebuf[0]);
student_name_ = linebuf[1];
uc_code_ = parse_uc(linebuf[2]);
class_code_ = parse_class(linebuf[3]);
}


// Getters
uint32_t StudentsClasses::get_student_code() const { return student_code_; }
std::string StudentsClasses::get_student_name() const { return student_name_; }
uint16_t StudentsClasses::get_uc_code() const { return uc_code_; }
uint16_t StudentsClasses::get_class_code() const { return class_code_; }


// Parsers
uint32_t StudentsClasses::parse_student_code(const std::string& student_code) const {
std::istringstream iss(student_code);
uint32_t student_code_int;
iss >> student_code_int;
return student_code_int;
}

uint16_t StudentsClasses::parse_uc(const std::string& uc_code) const {
uint64_t hash = 5381;
jvdcf marked this conversation as resolved.
Show resolved Hide resolved
std::string num_part;
for (char c : uc_code) {
if (!isnum(c)) {
hash = (hash << 5) + hash + c;
}
if (isnum(c)) {
num_part.push_back(c);
}
}
try {
uint8_t num = 0;
if (num_part != "") {
num = std::stoi(num_part);
}
return (uint16_t)((hash % 256) << 8) + (uint16_t)(num);
} catch (std::invalid_argument &e) {
std::cerr << e.what() << " uc: failed to parse" << '\n';
std::exit(1);
}
}

uint16_t StudentsClasses::parse_class(std::string class_code) const {
uint8_t year = class_code[0] - '0';
std::string classnum;
for (int i = 1; i < class_code.size(); ++i) {
if (isnum(class_code[i])) {
classnum.push_back(class_code[i]);
}
}
try {
uint8_t num = 0;
if (classnum != "") {
num = std::stoi(classnum);
}
return ((uint16_t)year << 8) + num;
} catch (std::invalid_argument &e) {
std::cerr << e.what() << " class: failed to parse" << '\n';
std::exit(1);
}
}


// String format
void StudentsClasses::student_code_to_str(std::string& student_code) const {
student_code = std::to_string(student_code_);
}

void StudentsClasses::uc_code_to_str(std::string& uc_code) const {
std::stringstream s;
std::string classname;
bool found = false;
uint16_t hash_of_class = uc_code_ >> 8;
for (int i = 0; i <= sizeof(this->types_of_uc) / sizeof(char *); ++i) {
if (hash_of_class == hash_str(std::string(this->types_of_uc[i]))) {
classname = this->types_of_uc[i];
found = true;
break;
}
}
if (!found) {
std::cerr << "There is no known uc type with hash " << hash_of_class
<< "!\n";
std::exit(1);
}
s << classname << std::setfill('0') << std::setw(3) << (uc_code_ & 255);
uc_code = s.str();
}

void StudentsClasses::class_code_to_str(std::string& class_code) const {
std::stringstream s;
// TODO: use exceptions to handle errors instead of closing.
if ((class_code_ >> 8) == 19) {
class_code = "ClassCode";
return;
}
s << (class_code_ >> 8) << "LEIC" << std::setfill('0') << std::setw(2)
<< (class_code_ & 255);
class_code = s.str();
}


// Debug
void StudentsClasses::display() const {
std::string student_code;
std::string student_name = get_student_name();
std::string uc_code;
std::string class_code;
student_code_to_str(student_code);
uc_code_to_str(uc_code);
class_code_to_str(class_code);
std::cout << student_code << ","
<< student_name << ","
<< uc_code << ","
<< class_code << '\n';
}
40 changes: 40 additions & 0 deletions src/studentsClasses.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <string>
#include <cstdint>
#ifndef STUDENTSCLASSES_H
#define STUDENTSCLASSES_H

class StudentsClasses {
private:
uint32_t student_code_;
std::string student_name_;
uint16_t uc_code_;
uint16_t class_code_;
constexpr const static char *types_of_uc[] = {
"L.EIC", "UP", "IAPD", "CSR", "IADE", "IR", "MPSAC", "DDS", "SEESTE"};

public:
// Constructor
StudentsClasses(std::string& line);

// Getters
uint32_t get_student_code() const;
std::string get_student_name() const;
uint16_t get_uc_code() const;
uint16_t get_class_code() const;

// Parsers
uint32_t parse_student_code(const std::string& student_code) const;
uint16_t parse_uc(const std::string& uc_code) const;
uint16_t parse_class(std::string class_code) const;

// String format
void student_code_to_str(std::string& student_code) const;
// void student_name_to_str(std::string& student_name) const; (= get_student_name())
void uc_code_to_str(std::string& uc_code) const;
void class_code_to_str(std::string& class_code) const;

// Debug
void display() const;
};

#endif // STUDENTSCLASSES_H