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

Listing for Student, Class and UC #37

Merged
merged 11 commits into from
Nov 2, 2023
16 changes: 16 additions & 0 deletions src/ClassSchedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <cstdint>
#include <cstdio>
#include <vector>
#include <algorithm>

/**
* @brief Constructor of the class.
Expand Down Expand Up @@ -74,6 +75,21 @@ std::vector<Lesson*>* ClassSchedule::get_class_schedule() {
return &this->classes;
}

void ClassSchedule::sort() {
std::sort(this->classes.begin(), this->classes.end(), [](Lesson *a, Lesson *b) {
if (a->get_day() == b->get_day()) {
if (a->get_start_hour() == b->get_start_hour()) {
if (a->get_duration() == b->get_duration()) {
return a->get_type() < b->get_type();
}
else return a->get_duration() < b->get_duration();
}
else return a->get_start_hour() < b->get_start_hour();
}
else return a->get_day() < b->get_day();
});
}

/**
* @brief Prints to the screen the contents of this class.
*/
Expand Down
1 change: 1 addition & 0 deletions src/ClassSchedule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ClassSchedule : public ClassPerUC {
void remove_student();
uint64_t get_student_count() const;
std::vector<Lesson*>* get_class_schedule();
void sort();
void display() const;
};

Expand Down
1 change: 1 addition & 0 deletions src/Lesson.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum class WeekDay {
THURSDAY,
FRIDAY,
SATURDAY,
NONE,
};

/**
Expand Down
5 changes: 4 additions & 1 deletion src/Process.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ enum class TypeOfRequest {
Add,
Remove,
Switch,
Print,
Print_Student,
Print_UC,
Print_Class,
Batch,
};

Expand All @@ -15,6 +17,7 @@ class Process {
private:
TypeOfRequest type;
std::vector<std::string> operands;

public:
Process(TypeOfRequest t);
void add_operand(std::string s);
Expand Down
221 changes: 198 additions & 23 deletions src/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
#include "Runtime.hpp"
#include "ClassSchedule.hpp"
#include "Lesson.hpp"
#include "Student.hpp"
#include "Utils.hpp"
#include <algorithm>
Expand All @@ -11,6 +12,7 @@
#include <cstdio>
#include <cstdlib>
#include <exception>
#include <iomanip>
#include <iostream>
#include <ostream>
#include <queue>
Expand Down Expand Up @@ -40,9 +42,11 @@ Runtime::Runtime(CSVStudentsClasses &sc, CSVClassPerUC &cpu, CSVClasses &c) {
}
break;
}
cs.sort();
classes.push_back(cs);
}


// 3. Populate students
sc.sort_by(std::string("StudentCode"));
auto sc_vector = sc.get_students();
Expand Down Expand Up @@ -83,6 +87,41 @@ ClassSchedule *Runtime::find_class(uint32_t id) {
return nullptr;
}

/**
* @brief Find all the classes with the same uc_code.
* @param uc_code
* @return Vector with pointers to the found ClassSchedules, or empty vector if not found.
*/
std::vector<ClassSchedule *> Runtime::find_uc(uint16_t uc_code) {
std::vector<ClassSchedule *> ret;
size_t high = classes.size();
size_t low = 0;

while (low <= high) {
size_t mid = low + (high - low) / 2;
if (classes[mid].get_uc_code() < uc_code) {
low = mid + 1;
} else if (classes[mid].get_uc_code() > uc_code){
high = mid - 1;
} else { // == id
while (classes[mid].get_uc_code() == uc_code) {
mid--;
}
mid++;
while (classes[mid].get_uc_code() == uc_code) {
ret.push_back(&classes[mid]);
mid++;
}
return ret;
}
}

// If not found, return empty vector
return ret;
}

// ----------------------------------------------------------------------------------------------------

void Runtime::run() {
std::string in;
std::istringstream stream;
Expand Down Expand Up @@ -168,33 +207,69 @@ void Runtime::process_args(std::vector<std::string> args) {
}
}
if (args[0] == "print") {
guilherme-ds-matos marked this conversation as resolved.
Show resolved Hide resolved
if (args.size() != 2) {
std::cerr << "ERROR: USAGE: print takes 1 argument: print <student_code>"
<< std::endl;
if (args.size() < 2) {
std::cerr << "ERROR: USAGE: print student takes 1 argument: print student <student_code>\n"
<< " USAGE: print uc takes 1 argument: print uc <uc_code>\n"
<< " USAGE: print class takes 2 argument: print class <uc_code> <class_code>\n";
return;
} else if (args[1] == "student") {
if (args.size() != 3) {
std::cerr << "ERROR: USAGE: print student takes 1 argument: print student <student_code>\n";
return;
} else {
Process t(TypeOfRequest::Print_Student);
t.add_operand(args[2]);
procs.push(t);
return;
}
} else if (args[1] == "uc") {
if (args.size() != 3) {
std::cerr << "ERROR: USAGE: print uc takes 1 argument: print uc <uc_code>\n";
return;
} else {
Process t(TypeOfRequest::Print_UC);
t.add_operand(args[2]);
procs.push(t);
return;
}
} else if (args[1] == "class") {
if (args.size() != 4) {
std::cerr << "ERROR: USAGE: print class takes 2 argument: print class <uc_code> <class_code>\n";
return;
} else {
Process t(TypeOfRequest::Print_Class);
t.add_operand(args[2]);
t.add_operand(args[3]);
procs.push(t);
return;
}
} else {
Process t(TypeOfRequest::Print);
t.add_operand(args[1]);
procs.push(t);
std::cerr << "ERROR: No such command " << args[0] << ' ' << args[1]
<< ". Try typing 'help' to know the available commands."
<< std::endl;
return;
}

}

if (args[0] == "help") {
std::cout << "The available commands are:\n\n" <<
" print: takes 1 argument: print <student_code>\n" <<
" Prints the student name, the student code and the student schedule.\n\n" <<
" add: takes 3 arguments: add <student_code> <uc_code> <class_code>\n" <<
std::cout << "The available commands are:\n" <<
" print student: takes 1 argument: print student <student_code>\n" <<
" Prints the student name, enrolled classes and schedule.\n\n" <<
" print uc: takes 1 argument: print uc <uc_code>\n" <<
" Prints all the classes associated with this UC.\n\n" <<
" print class: takes 2 argument: print class <uc_code> <class_code>\n" <<
" Prints the number of students enrolled and the schedule.\n\n" <<
" add: takes 3 arguments: add <student_code> <uc_code> <class_code>\n" <<
" Adds a student to a class if possible.\n\n" <<
" remove: takes 2 arguments: remove <student_code> <uc_code>\n" <<
" remove: takes 2 arguments: remove <student_code> <uc_code>\n" <<
" Removes a student from a class if possible.\n\n" <<
" switch: takes 3 arguments: switch <student_code> <student_code> <uc_code>\n" <<
" switch: takes 3 arguments: switch <student_code> <student_code> <uc_code>\n" <<
" Switches the class of two students.\n\n" <<
" quit: takes 0 arguments: quit\n" <<
" quit: takes 0 arguments: quit\n" <<
" Quits the program.\n\n" <<
" help: takes 0 arguments: help\n" <<
" Prints this help." <<
std::endl;
" help: takes 0 arguments: help\n" <<
" Prints this help.\n\n";
return;
}

Expand All @@ -205,6 +280,7 @@ void Runtime::process_args(std::vector<std::string> args) {

void Runtime::handle_process(Process p) {
std::vector<std::string> ops = p.get_ops();

// handle remove
if (p.get_type() == TypeOfRequest::Remove) {
uint32_t student_code;
Expand Down Expand Up @@ -237,30 +313,129 @@ void Runtime::handle_process(Process p) {
}
return;
}
// End Remove

if (p.get_type() == TypeOfRequest::Print) {
// handle print student
if (p.get_type() == TypeOfRequest::Print_Student) {
uint32_t student_code;
try {
student_code = std::stoi(ops[0]);
} catch (std::exception e) {
} catch (std::exception& e) {
std::cerr << "ERROR: The string " << ops[0] << " is not a student_code."
<< std::endl;
return;
}
if (auto itr = students.find(Student(student_code, ""));
itr != students.end()) {
Student s = *itr;
std::cout << "Name: " << s.get_name() << "\nCode: " << s.get_code()
<< std::endl;

// Name and Code:
std::cout << "Name: " << s.get_name() << "\nCode: " << s.get_code() << "\n\n";

// Classes:
std::cout << "Classes enrolled: \n";
for (ClassSchedule *class_ : s.get_schedule()) {
std::string class_code;
class_->class_to_str(class_code);
std::string uc_code;
class_->uc_to_str(uc_code);
std::cout << uc_code << ": " << class_code << std::endl;
}
std::cout << std::endl;

// Schedule:
// Group all Lessons into one Schedule
std::vector<ClassSchedule *> sched = s.get_schedule();
for (auto i : sched) {
i->display();
std::vector<Lesson*> grouped;
for (ClassSchedule *class_ : sched) {
for (Lesson *lesson : *class_->get_class_schedule()) {
guilherme-ds-matos marked this conversation as resolved.
Show resolved Hide resolved
grouped.push_back(lesson);
}
}
std::sort(grouped.begin(), grouped.end(), [](Lesson *a, Lesson *b) {
if (a->get_day() == b->get_day()) {
if (a->get_start_hour() == b->get_start_hour()) {
if (a->get_duration() == b->get_duration()) {
return a->get_type() < b->get_type();
}
else return a->get_duration() < b->get_duration();
}
else return a->get_start_hour() < b->get_start_hour();
}
else return a->get_day() < b->get_day();
});

print_schedule(grouped);

} else {
std::cerr << "ERROR: There is no such student with code: " << student_code
<< std::endl;
}
return;
}

// handle print uc
if (p.get_type() == TypeOfRequest::Print_UC) {
uint16_t uc_code = parse_uc_gen(ops[0]);
std::vector<ClassSchedule *> classes_found = find_uc(uc_code);

if (classes_found.empty()) {
std::cerr << "ERROR: There is no such uc_code.\n";
return;
}

std::cout << "Classes with uc_code " << ops[0] << ":\n";
for (auto i : classes_found) {
std::string class_code;
i->class_to_str(class_code);
std::cout << class_code << std::endl;
}
return;
}

// handle print class
if (p.get_type() == TypeOfRequest::Print_Class) {
uint16_t uc_code = parse_uc_gen(ops[0]);
uint16_t class_code = parse_class_gen(ops[1]);
uint32_t id = ((uint32_t)uc_code << 16) + class_code;
ClassSchedule* cs = find_class(id);

if (cs == nullptr) {
std::cerr << "ERROR: There is no such class.\n";
return;
}

std::cout << "Class " << ops[1] << ":\n"
<< "Number of students: " << cs->get_student_count() << '\n';

print_schedule(*cs->get_class_schedule());
return;
}
}

void Runtime::print_schedule(const std::vector<Lesson *>& schedule) const {
//std::cout << "Schedule:\n" << "(Type | Day | Start Time | Duration | UC | Class)\n";
int start_hour;
int start_minutes;
WeekDay day = WeekDay::NONE;
std::string day_str;
for (Lesson *lesson: schedule) {
if (lesson->get_day() != day) {
day = lesson->get_day();
lesson->day_to_str(day_str);
std::cout << std::setw(19) << day_str << std::setw(0) << std::endl;
}
start_hour = static_cast<int>(lesson->get_start_hour());
guilherme-ds-matos marked this conversation as resolved.
Show resolved Hide resolved
start_minutes = (lesson->get_start_hour() - start_hour) * 60;
std::string type;
lesson->type_to_str(type);
std::string uc;
lesson->uc_to_str(uc);
std::string class_;
lesson->class_to_str(class_);

std::cout << std::setw(2) << type << std::setw(0) << " | " << std::setw(2) << start_hour << std::setw(0);
std::cout << ':' << std::setw(2) << std::setfill('0') << start_minutes << std::setfill(' ');
std::cout << " | " << std::setw(3) << lesson->get_duration() << "h"
<< " | " << std::setw(7) << uc << std::setw(0) << " | " << std::setw(7) << class_ << std::setw(0) << '\n';
}
}
4 changes: 4 additions & 0 deletions src/Runtime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ class Runtime {
uint8_t cap;
bool is_batching;

void print_schedule(const std::vector<Lesson*>& schedule) const;

public:
Runtime(CSVStudentsClasses &sc, CSVClassPerUC &cpu, CSVClasses &c);

// Sorting

// Searching
ClassSchedule* find_class(uint32_t id);
std::vector<ClassSchedule*> find_uc(uint16_t uc_code);

// TODO
void run();
void process_args(std::vector<std::string> args);
Expand Down
Loading