#include "Patient.hpp" #include #include #include #include #include #include #ifndef CLINIC_ #define CLINIC_ enum class MenuChoice { NewPatient = 1, NewVisit = 2, DisplayPatient = 3, Quit = 4, }; struct Clinic { public: std::vector patients; std::string filename; private: // C++ types are getting crazy here :( I really miss Rust // `std::optional` needed because a patient might not be found // `std::reference_wrapper` because `std::optional` deoesn't accept references // I want to reference because (I want to save cpu cycles from memory copies) std::optional> find_patient(u_int32_t patient_id) { auto it = std::find_if(patients.begin(), patients.end(), [&id = patient_id](const Patient &p) -> bool { return p.get_id() == id; }); if (it != patients.end()) return *it; return std::nullopt; }; public: Clinic(std::string filename) : filename(filename) { /// this file contains a list of patient IDs. // 1 // 2 // 4 (could be non-sequential // but always sorted!) u_int32_t patient_id; std::ifstream file{filename}; if (!file.is_open()) { std::cerr << "File " << filename << " couldn't be opened :(\n"; exit(1); } while (file >> patient_id) patients.push_back(Patient(patient_id)); } // writes the patients.txt file containing patient IDs. void write_file() { std::ofstream file{filename}; for (auto p : patients) file << p.get_id() << "\n"; } u_int32_t generate_id() { u_int32_t id{}; // O(n), could be improved by using UUIDs, or store max_id in Clinic for (auto p : patients) id = std::max(id, p.get_id()); id++; return id; } MenuChoice menu_main() { int choice{}; std::cout << "==============================================\n"; std::cout << "Please choose a command:\n"; std::cout << "1. add new patient\n"; std::cout << "2. add new visit\n"; std::cout << "3. display patient information\n"; std::cout << "4. quit\n"; std::cout << ">> "; std::cin >> choice; while (choice < int(MenuChoice::NewPatient) || choice > int(MenuChoice::Quit)) { std::cout << "Invalid input! Try again :)\n"; std::cout << "Please choose a command:\n"; std::cout << "1. add new patient\n"; std::cout << "2. add new visit\n"; std::cout << "3. display patient information\n"; std::cout << "4. quit\n"; std::cout << ">> "; std::cin >> choice; } return static_cast(choice); } void menu_patient_info() { int patient_id; std::cout << "Patient file number: "; std::cin >> patient_id; auto patient = find_patient(patient_id); if (patient.has_value()) std::cout << patient.value(); else std::cout << "No Patient exists with id= " << patient_id << "\n"; std::cout << "--------------------\n\n"; } void menu_add_new_patient() { std::string reading_string; std::string input_string; Patient patient{}; std::stringstream patient_stream; // not the most optimal way, but the lazy way // see: https://ammar.engineer/posts/2023/06/03/laziness/ // this "emulates" a file so that I can resuse my >> operator reading_string += std::to_string(generate_id()) + "\n"; std::cout << "Generate " << reading_string; std::cout << "First name (no spaces): "; std::cin >> input_string; reading_string += input_string + "\n"; std::cout << "Last name (no spaces): "; std::cin >> input_string; reading_string += input_string + "\n"; std::cout << "Gender (M or F): "; std::cin >> input_string; reading_string += input_string + "\n"; std::cout << "Age: "; std::cin >> input_string; reading_string += input_string + "\n"; std::cout << reading_string; patient_stream = std::stringstream(reading_string); // all of that just for this moment: patient_stream >> patient; patients.push_back(patient); // save in memory patient.write_patient(); // write to file write_file(); } void menu_add_vist() { std::string reading_string; std::string input_string; int patient_id; std::cout << "Patient file number: "; std::cin >> patient_id; std::cout << "Date:"; std::cin >> input_string; reading_string += input_string + " "; std::cout << "Doctor's First Name: "; std::cin >> input_string; reading_string += input_string + " "; std::cout << "Doctors's Last Name: "; std::cin >> input_string; reading_string += input_string + " "; std::stringstream visit_stream = std::stringstream(reading_string); Visit visit; visit_stream >> visit; auto patient = find_patient(patient_id); if (patient.has_value()) patient.value().get().add_visit(visit); else std::cout << "No Patient exists with id= " << patient_id << "\n"; } }; #endif