online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
#include <iostream> #include <limits> #include <iomanip> #include <fstream> #include "StudentProfile.hpp" #include "JobParser.hpp" #include "Sorter.hpp" using namespace std; // Function to clear input buffer void clearInputBuffer() { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); } // Function to get yes/no input bool getYesNo(const string& prompt) { string input; while (true) { cout << prompt << " (y/n): "; getline(cin, input); if (input == "y" || input == "Y") return true; if (input == "n" || input == "N") return false; cout << "Please enter 'y' or 'n'.\n"; } } // Function to get multiple entries from user vector<string> getMultipleEntries(const string& itemName) { vector<string> entries; string input; cout << "\nEnter " << itemName << " (one per line). Press Enter on empty line to finish:\n"; while (true) { cout << "> "; getline(cin, input); if (input.empty()) { if (entries.empty()) { cout << "No " << itemName << " entered. Try again or press Enter to skip.\n"; continue; } break; } entries.push_back(input); } return entries; } // Function to build student profile interactively StudentProfile buildStudentProfile() { StudentProfile student; string input; cout << "\n" << string(60, '=') << "\n"; cout << " STUDENT PROFILE CREATION\n"; cout << string(60, '=') << "\n\n"; // Basic Information cout << "Let's start with your basic information:\n"; cout << "Enter your full name: "; getline(cin, input); student.setName(input); cout << "Enter your major: "; getline(cin, input); student.setMajor(input); // Remote preference (the only preference we keep) student.setWantRemote(getYesNo("\nAre you willing to work remotely?")); // Skills cout << "\nNow, let's add your skills.\n"; student.setSkills(getMultipleEntries("skills")); // Experiences bool addExperiences = getYesNo("\nWould you like to add your work experiences?"); if (addExperiences) { student.setExperiences(getMultipleEntries("experiences")); } // Interests bool addInterests = getYesNo("\nWould you like to add your interests?"); if (addInterests) { student.setInterests(getMultipleEntries("interests")); } // Projects bool addProjects = getYesNo("\nWould you like to add your projects?"); if (addProjects) { student.setProjects(getMultipleEntries("projects")); } // Courses bool addCourses = getYesNo("\nWould you like to add relevant courses?"); if (addCourses) { student.setCourses(getMultipleEntries("courses")); } // Display the completed profile student.displayProfile(); // Ask if profile is correct bool correct = getYesNo("\nIs this profile correct?"); if (!correct) { cout << "\nLet's try again. Starting over...\n"; return buildStudentProfile(); } return student; } // Function to load and parse job files vector<Job> loadAllJobFiles(const vector<string>& filenames) { vector<Job> allJobs; cout << "\nLOADING JOB DESCRIPTIONS\n"; for (const auto& filename : filenames) { cout << "Processing " << filename << "...\n"; JobParser parser(filename); vector<Job> jobs = parser.loadAllJobs(); // Add all jobs from this file to the master list allJobs.insert(allJobs.end(), jobs.begin(), jobs.end()); cout << "Found " << jobs.size() << " job(s) in " << filename << "\n\n"; } cout << "Total jobs loaded: " << allJobs.size() << "\n"; return allJobs; } // Function to display ranking summary void displayRankingSummary(const vector<pair<Job, double>>& rankedJobs) { cout << "\nQUICK RANKING SUMMARY\n"; for (size_t i = 0; i < min(3, (int)rankedJobs.size()); ++i) { const auto& job = rankedJobs[i].first; double score = rankedJobs[i].second; cout << i+1 << ". " << job.getTitle() << " at " << job.getCompany() << " - " << fixed << setprecision(1) << score << "%\n"; } if (rankedJobs.size() > 3) { cout << "... and " << rankedJobs.size() - 3 << " more jobs\n"; } } int main() { cout << "\n"; cout << "** JOB RANKING SYSTEM FOR STUDENTS **\n\n"; // Step 1: Build student profile cout << "First, let's create your student profile.\n"; StudentProfile student = buildStudentProfile(); // Step 2: Load job files cout << "\nNow, let's load the job descriptions.\n"; vector<string> jobFiles; // Check if Job1.txt exists and add it ifstream file1("Job1.txt"); if (file1.good()) { jobFiles.push_back("Job1.txt"); file1.close(); } else { cout << "Warning: Job1.txt not found. Creating a sample file...\n"; ofstream sample("Job1.txt"); sample << "Software Engineering Intern\n"; sample << "Tech Company\n\n"; sample << "We are looking for a Python developer with experience in JavaScript and SQL.\n"; sample << "This is a remote position. Salary: $30/hr.\n"; sample << "Undergraduate students welcome to apply.\n"; sample << "---\n"; sample.close(); jobFiles.push_back("Job1.txt"); } ifstream file2("Job2.txt"); if (file2.good()) { jobFiles.push_back("Job2.txt"); file2.close(); } else { cout << "Warning: Job2.txt not found. Creating a sample file...\n"; ofstream sample("Job2.txt"); sample << "GIS Co-op Student\n"; sample << "YVR Airport\n\n"; sample << "Experience with ArcGIS Pro, FME, and ESRI Field Maps required.\n"; sample << "Salary range: $24.80-$27.33/hr. On-site position in Vancouver.\n"; sample << "Undergraduate students in GIS or related field.\n"; sample << "---\n"; sample.close(); jobFiles.push_back("Job2.txt"); } // Step 3: Parse all job files vector<Job> allJobs = loadAllJobFiles(jobFiles); if (allJobs.empty()) { cout << "\nNo jobs found to rank. Exiting...\n"; return 1; } // Step 4: Rank the jobs cout << "\nRANKING JOBS...\n"; Sorter sorter; // Ask user if they want to adjust weights bool adjustWeights = getYesNo("\nWould you like to adjust the ranking weights?"); if (adjustWeights) { cout << "\nEnter weights (should sum to 1.0):\n"; cout << "(Skills, Interests, Remote, Industry Experience)\n"; double skills, interests, remote, industry; cout << "Skills weight (default 0.50): "; cin >> skills; cout << "Interests weight (default 0.15): "; cin >> interests; cout << "Remote weight (default 0.10): "; cin >> remote; cout << "Industry experience weight (default 0.25): "; cin >> industry; clearInputBuffer(); // Clear the input buffer sorter.setWeights(skills, interests, remote, industry); } // Sort the jobs auto rankedJobs = sorter.sortJobs(allJobs, student); // Step 5: Display rankings cout << "\n"; sorter.displayRankings(rankedJobs, student); // Step 6: Show summary displayRankingSummary(rankedJobs); // Step 7: Option to save rankings bool saveRankings = getYesNo("\nWould you like to save the rankings to a file?"); if (saveRankings) { string filename; cout << "Enter filename to save (e.g., rankings.txt): "; getline(cin, filename); ofstream file(filename); if (file.is_open()) { // Save the summary file << "JOB RANKINGS FOR " << student.getName() << "\n"; file << string(50, '=') << "\n\n"; for (size_t i = 0; i < rankedJobs.size(); ++i) { const auto& job = rankedJobs[i].first; double score = rankedJobs[i].second; file << i+1 << ". " << job.getTitle() << " at " << job.getCompany() << " - " << fixed << setprecision(1) << score << "%\n"; } file.close(); cout << "Rankings saved to " << filename << "\n"; } else { cout << "Error saving rankings.\n"; } } cout << "\nThank you for using the Job Ranking System!\n"; return 0; }
#include "Job.hpp" #include <iostream> #include <iomanip> #include <sstream> using namespace std; // Constructor Job::Job() : isRemote(false), salary(0.0) {} // Setters void Job::setTitle(const string& newTitle) { title = newTitle; } void Job::setCompany(const string& newCompany) { company = newCompany; } void Job::setJobSkills(const vector<string>& newSkills) { jobSkills = newSkills; } void Job::setExperienceLevel(const string& newLevel) { experienceLevel = newLevel; } void Job::setRemote(bool remote) { isRemote = remote; } void Job::setSalary(double newSalary) { salary = newSalary; } void Job::setIndustries(const vector<string>& newIndustries) { industries = newIndustries; } // Getters string Job::getTitle() const { return title; } string Job::getCompany() const { return company; } const vector<string>& Job::getRequiredSkills() const { // Changed name return jobSkills; } string Job::getExperienceLevel() const { return experienceLevel; } bool Job::getRemote() const { return isRemote; } double Job::getSalary() const { return salary; } const vector<string>& Job::getIndustries() const { return industries; } // Display function void Job::displayJob() const { cout << "\n" << string(50, '-') << "\n"; cout << "Job: " << title << " at " << company << "\n"; cout << string(50, '-') << "\n"; if (isRemote) cout << " (Remote)"; cout << "\n"; cout << "Experience: " << experienceLevel << "\n"; cout << "Salary: $" << fixed << setprecision(2) << salary << "\n"; cout << "Required Skills:\n"; for (const auto& skill : jobSkills) { cout << " • " << skill << "\n"; } cout << "Industries:\n"; for (const auto& industry : industries) { cout << " • " << industry << "\n"; } } // To string function for file parsing string Job::toString() const { stringstream ss; ss << "TITLE:" << title << "\n"; ss << "COMPANY:" << company << "\n"; ss << "REMOTE:" << (isRemote ? "yes" : "no") << "\n"; // Removed location ss << "EXPERIENCE:" << experienceLevel << "\n"; ss << "SALARY:" << salary << "\n"; ss << "SKILLS:"; for (size_t i = 0; i < jobSkills.size(); ++i) { if (i > 0) ss << ","; ss << jobSkills[i]; } ss << "\n"; ss << "INDUSTRIES:"; for (size_t i = 0; i < industries.size(); ++i) { if (i > 0) ss << ","; ss << industries[i]; } ss << "\n"; return ss.str(); // Removed description reference }
// Defines Job class #ifndef JOB_HPP #define JOB_HPP #include <string> #include <vector> using namespace std; class Job { private: string title; string company; vector<string> jobSkills; string experienceLevel; //undergraduate vs. masters vs. phd bool isRemote; double salary; vector<string> industries; public: // Constructor Job(); // Setters void setTitle(const string& newTitle); void setCompany(const string& newCompany); void setJobSkills(const vector<string>& newSkills); void setExperienceLevel(const string& newLevel); void setRemote(bool remote); void setSalary(double newSalary); void setIndustries(const vector<string>& newIndustries); // Getters (const because they don't modify) string getTitle() const; string getCompany() const; const vector<string>& getRequiredSkills() const; string getExperienceLevel() const; bool getRemote() const; double getSalary() const; const vector<string>& getIndustries() const; // Other void displayJob() const; string toString() const; // For saving to file }; #endif
// Student profile class #include "StudentProfile.hpp" #include <iostream> #include <algorithm> #include <sstream> #include <iomanip> using namespace std; //Constructor StudentProfile::StudentProfile() : wantRemote(false) { } //Set functions void StudentProfile::setName(const string& newName) { name = newName; } void StudentProfile::setMajor(const string& newMajor) { major = newMajor; } void StudentProfile::setWantRemote(bool remote) { wantRemote = remote; } void StudentProfile::setSkills(const vector<string>& newSkills) { skills = newSkills; } void StudentProfile::setExperiences(const vector<string>& newExperiences) { experiences = newExperiences; } void StudentProfile::setInterests(const vector<string>& newInterests) { interests = newInterests; } void StudentProfile::setProjects(const vector<string>& newProjects) { projects = newProjects; } void StudentProfile::setCourses(const vector<string>& newCourses) { courses = newCourses; } //Get functions string StudentProfile::getName() const { return name; } string StudentProfile::getMajor() const { return major; } bool StudentProfile::getWantRemote() const { return wantRemote; } const vector<string>& StudentProfile::getSkills() const { return skills; } const vector<string>& StudentProfile::getExperiences() const { return experiences; } const vector<string>& StudentProfile::getInterests() const { return interests; } const vector<string>& StudentProfile::getProjects() const { return projects; } const vector<string>& StudentProfile::getCourses() const { return courses; } // File parsing string StudentProfile::toString() const { stringstream ss; // Basic info ss << "NAME:" << name << "\n"; ss << "MAJOR:" << major << "\n"; ss << "REMOTE:" << (wantRemote ? "yes" : "no") << "\n"; // Skills ss << "SKILLS:"; for (size_t i = 0; i < skills.size(); ++i) { if (i > 0) ss << ","; ss << skills[i]; } ss << "\n"; // Experiences ss << "EXPERIENCES:"; for (size_t i = 0; i < experiences.size(); ++i) { if (i > 0) ss << ","; ss << experiences[i]; } ss << "\n"; // Interests ss << "INTERESTS:"; for (size_t i = 0; i < interests.size(); ++i) { if (i > 0) ss << ","; ss << interests[i]; } ss << "\n"; // Projects ss << "PROJECTS:"; for (size_t i = 0; i < projects.size(); ++i) { if (i > 0) ss << ","; ss << projects[i]; } ss << "\n"; // Courses ss << "COURSES:"; for (size_t i = 0; i < courses.size(); ++i) { if (i > 0) ss << ","; ss << courses[i]; } ss << "\n"; return ss.str(); } void StudentProfile::fromString(const string& data) { stringstream ss(data); string line; while (getline(ss, line)) { size_t colonPos = line.find(':'); if (colonPos == string::npos) continue; string key = line.substr(0, colonPos); string value = line.substr(colonPos + 1); if (key == "NAME") { name = value; } else if (key == "MAJOR") { major = value; } else if (key == "REMOTE") { wantRemote = (value == "yes"); } else if (key == "SKILLS") { skills.clear(); stringstream skillSS(value); string skill; while (getline(skillSS, skill, ',')) { if (!skill.empty()) skills.push_back(skill); } } else if (key == "EXPERIENCES") { experiences.clear(); stringstream expSS(value); string exp; while (getline(expSS, exp, ',')) { if (!exp.empty()) experiences.push_back(exp); } } else if (key == "INTERESTS") { interests.clear(); stringstream interestSS(value); string interest; while (getline(interestSS, interest, ',')) { if (!interest.empty()) interests.push_back(interest); } } else if (key == "PROJECTS") { projects.clear(); stringstream projectSS(value); string project; while (getline(projectSS, project, ',')) { if (!project.empty()) projects.push_back(project); } } else if (key == "COURSES") { courses.clear(); stringstream courseSS(value); string course; while (getline(courseSS, course, ',')) { if (!course.empty()) courses.push_back(course); } } } } // Display function void StudentProfile::displayProfile() const { cout << "\n" << string(50, '=') << "\n"; cout << " STUDENT PROFILE\n"; cout << string(50, '=') << "\n\n"; // Basic Information cout << "BASIC INFORMATION:\n"; cout << " Name: " << name << "\n"; cout << " Major: " << major << "\n"; cout << " Remote: " << (wantRemote ? "Yes" : "No") << "\n\n"; // Skills cout << "SKILLS (" << skills.size() << "):\n"; if (skills.empty()) { cout << " None listed\n"; } else { for (const auto& skill : skills) { cout << " • " << skill << "\n"; } } cout << "\n"; // Experiences cout << "EXPERIENCES (" << experiences.size() << "):\n"; if (experiences.empty()) { cout << " None listed\n"; } else { for (const auto& exp : experiences) { cout << " • " << exp << "\n"; } } cout << "\n"; // Interests cout << "INTERESTS (" << interests.size() << "):\n"; if (interests.empty()) { cout << " None listed\n"; } else { for (const auto& interest : interests) { cout << " • " << interest << "\n"; } } cout << "\n"; // Projects cout << "PROJECTS (" << projects.size() << "):\n"; if (projects.empty()) { cout << " None listed\n"; } else { for (const auto& project : projects) { cout << " • " << project << "\n"; } } cout << "\n"; // Courses cout << "COURSES (" << courses.size() << "):\n"; if (courses.empty()) { cout << " None listed\n"; } else { for (const auto& course : courses) { cout << " • " << course << "\n"; } } cout << "\n"; cout << "\n" << string(50, '=') << "\n"; } // Clear function void StudentProfile::clearAll() { name.clear(); major.clear(); wantRemote = false; skills.clear(); experiences.clear(); interests.clear(); projects.clear(); courses.clear(); }
// Defines student profile class #ifndef STUDENT_PROFILE_HPP #define STUDENT_PROFILE_HPP #include <string> #include <vector> #include <iostream> #include <sstream> #include <iomanip> using namespace std; class StudentProfile { private: // Basic info string name; string major; // Lists of qualifications vector<string> skills; vector<string> experiences; vector<string> interests; vector<string> projects; vector<string> courses; // Preferences bool wantRemote; // Only preference left! public: //constructor StudentProfile(); //set functions void setName(const string& newName); void setMajor(const string& newMajor); void setWantRemote(bool remote); void setSkills(const vector<string>& newSkills); void setExperiences(const vector<string>& newExperiences); void setInterests(const vector<string>& newInterests); void setProjects(const vector<string>& newProjects); void setCourses(const vector<string>& newCourses); //get functions string getName() const; string getMajor() const; bool getWantRemote() const; const vector<string>& getSkills() const; const vector<string>& getExperiences() const; const vector<string>& getInterests() const; const vector<string>& getProjects() const; const vector<string>& getCourses() const; //file parsing string toString() const; // For saving to file void fromString(const string& data); // For loading from file //displaying void displayProfile() const; //clearing void clearAll(); }; #endif
Title: Co‑op Student - Engineering Services (GIS) Company: Vancouver Airport Authority YVR is Canada’s Pacific gateway to Asia and beyond supporting global connectivity, and getting more of Canada to the world. From supporting tourism and trade, to connecting friends and family, to investing in people and communities. Our work has an impact far beyond the terminal. Behind every flight is a team of talented professionals spanning a wide range of skillsets and experience: • Engineering, infrastructure, and asset management • Technology, analytics, and digital systems • Sustainability, climate, and environmental stewardship • Operations, safety, and emergency readiness • Commercial strategy, finance, and data commercialization • Communications, experience design, and people systems If you’re interested in a chance to be part of a people-first organization with a chance to make a real impact, this may be the opportunity for you. Your Coop Experience at YVR This isn’t just a summer job. It’s an experience you’ll carry forward. As a YVR coop student, you won’t just observe — you’ll have a chance to be hands on, contributing to significant projects with our YVR team. Depending on the role, you may: • Work on live operational, digital, or infrastructure initiatives • Analyze data that informs decision making at scale • Contribute to climate, safety, or sustainability outcomes • Support tools, models, or processes used by frontline teams • Help design better employee, passenger, or system experiences • Collaborate across departments in a fastmoving operational environment You’ll see how Canada’s second busiest airport moves 27-million passengers a year while driving safety, service, innovation, and accountability, with a clear view on how your work makes an impact. Your Specific Project In this role, you will use tools including ArcGIS Pro, Vertigis Studio and workflows, ArcGIS Portal, FME, and ESRI Field Maps to develop a more comprehensive tool to track planning, inspection, and maintenance of drainage infrastructure (ditches, culverts, piping, manholes, catch basins, and related assets). You will work with multiple departments to iterate on the tool, integrate feedback, and may expand the approach to track other construction and maintenance projects, activities, and assets. We’re looking for students who: • Are enrolled in a recognized postsecondary program • Are curious about how large systems actually work • Enjoy learning new tools, technologies, or ways of thinking • Ask thoughtful questions and follow them through • Care about doing meaningful work with real outcomes • Want experience that translates across industries You don’t need to know everything on day one —just the motivation to learn, contribute, and figure things out. Why a Co-Op at YVR? • Work at one of Canada’s busiest and most innovative airports • Contribute to projects tied directly to YVR’s 2026 Business Plan • Gain exposure to complex, multidisciplinary operations • Build experience that’s transferable across sectors • Learn alongside people who are invested in developing early talent • See how your work supports the province, the economy, and the public Ready for Takeoff? If you’re energized by big systems, real responsibility, and meaningful impact, we’d love to hear from you. Apply and help shape the future of aviation, infrastructure, and service at YVR. Additional Information: • Application deadline: March 20, 2026 • Start and End Date: May 4, 2026 – August 28, 2026 (4-month Term) • Hours of Work: 37.5 hours • Dress Code: Westcoast Business Casual • Number of Openings: 1 Salary Range : $24.80/hr + Living Wage top up to $27.33/hr Who We Are YVR is more than just an airport. We connect our beautiful province and all it has to offer to the world. We are all leaders and trailblazers for change and innovation, so no matter the department or team you’re a part of, the work you do matters. At YVR, we are flexible in everything we do. We will work together to find ways to deliver customer excellence that helps us all thrive. Whatever your background and wherever you’re from, you belong at YVR. If you have any questions about accessibility or require any assistance applying, please reach out at [email protected]. --- Title: Electronics Co-Op Company: EnerSys EnerSys is a global leader in stored energy solutions for industrial applications. We have over thirty manufacturing and assembly plants worldwide servicing over 10,000 customers in more than 100 countries. Worldwide headquarters are located in Reading, PA, USA with regional headquarters in Europe and Asia. We complement our extensive line of Motive Power and Energy Systems with a full range of integrated services and systems. With sales and service locations throughout the world, and over 100 years of battery experience, EnerSys is the power/full solution for stored DC power products. What We’re Offering • Culture: We value and strive for excellence in all that we do through innovative technology by creating long lasting relationships with our stakeholders, co-workers, and customers. We continually strive to foster teamwork, engagement and enhance our employee’s skills and competence by providing appropriate training. Compensation Range: 22.00-25.00 per hour Compensation may vary based on applicant's work experience, education level, skill set, and/or location. Job Purpose Alpha Technologies Ltd. is looking for an Electronics Co-Op to join the Engineering team in our Burnaby head office. We are looking for a co-op student to help define a test strategy, and then perform the tests, for some exciting new analog and digital products we are developing. The position involves working within the engineering team to fully understand the products and then working on the verification test plan for the prototype products. The candidate will perform the testing and troubleshooting, if necessary, using a variety of lab test equipment, and may also need to construct test jigs or other equipment as part of the test process. The candidate will also be responsible to create the test report. If problems are found, the student will work with the designers to help identify and implement solutions. The ideal candidate shall have a good working knowledge and experience with microprocessors, peripheral circuits, and switching power supplies. Essential Duties and Responsibilities • Design and develop hardware circuits for various test jigs, involving both analog and digital circuitry. • Familiarity with LTSPICE or similar would be desirable • Familiarity with basic op-amp circuits, transistor circuits, etc. • Familiarity with PCB CAD package like Altium would be an asset • Create design calculations and develop detailed design verification plans • Execute test plans, document and analyze results • Propose and implement design changes to the product based on testing • Prepare and maintain technical documentation • Work with the firmware and software team to develop solutions • Contribute to continuous improvements of existing systems. • Participate in the development of the department's strategic goals and direction Qualifications • Enrolled in a 4 year university pursuing an engineering degree. Electronics Engineering degree preferred. • Familiarity with a variety of test equipment, including oscilloscopes, spectrum analyzers, environmental chambers, etc. • Experience soldering SMT components. • Any experience with analog circuits, micro-processor based circuitry, switch-mode power supplies. • Creating test plans, executing testing and documenting results. • Requires strong written and verbal communication skills. • Ability to collaborate with team and stakeholders to derive options and solutions to problems. • Excellent analysis, problem solving, design and troubleshooting skills. • Thrives in a highly collaborative cross-functional environment. • Ability to work a full-time 40 hour per week schedule. • Ability to commute to the Burnaby location reliably. • Available to work between May 4 to August 28 , 2026. General Job Requirements • This position will work in an office setting, expect minimal physical demands. EnerSys provides equal employment opportunities to all employees and applicants for employment and prohibits discrimination and harassment of any type without regard to race, color, religion, age, sex, national origin, disability status, genetics, protected veteran status, sexual orientation, gender identity or expression, or any other characteristic protected by federal, state or local laws. Know Your Rights Know Your Rights (Spanish) We use artificial intelligence to screen, assess and select applicants for open positions, including for the purposes of reviewing and ranking application materials and scoring answers to application questions. Accordingly, decisions about your application and eligibility for employment with EnerSys may be made based exclusively on the automated processing of the personal information that you submit in your application materials
Title: Software Co-op Company: Cellula Robotics Job description Cellula is looking to add a Software Co-op to its Engineering team to support its growing list of engineering-to-order projects. This position will begin in May 2026. We are open to both 4 or 8 month co-op terms, but with a preference for 8 months. Cellula is an innovative engineering company that specializes in automated and tele-robotics systems; primarily for the offshore and subsea market space. Our solutions are designed, built, and tested in-house by a skilled team of engineers, technicians, and support staff. We take pride in what we do and work hard to bring the best value to our clients. We want to learn from the field so we can continually improve how we deliver solutions to our clients. To that end, we encourage the same team members who helped design & build our solutions to assist the client in the field with installation, operational trials, and service. As the Software Co-op, you will be responsible for working in the engineering team on the design, testing and commissioning of AUV (Autonomous Underwater Vehicle). General duties include supporting engineers in the testing, development and production of subsea robotic technology. Good communication skills and a willingness to learn are required, and students with an eager attitude and excellent work ethic will gain the most benefit. You will be exposed to aspects of the key disciplines involved: Electrical, Mechanical, Software and Project Management particularly from an software engineering point of view. As a company, we offer team members a chance to grow professionally with ever-changing projects. Our office is a casual, collaborative environment where you will be able to learn about our state-of-the-art systems from technical experts. In addition, we offer flexible work hours, benefits, and competitive compensation. This position is primarily an on-site position with some limited flexibility for remote work. Duties and Responsibilities • AUV software development and testing • Writing/reviewing software documentation, including design documents, test plans, and reports • System testing, including software tests, bench tests, and subsystem tests • Assisting with testing, troubleshooting, and commissioning AUV system • Assisting with operational objectives • Data review & analysis • Assist in system assembly, integration, and troubleshooting Required Skills & Experience • Currently enrolled in a Software Engineering, Mechatronics, or Computer Engineering program leading to a Bachelor’s degree or higher • Proficient communication skills, both written and oral • Problem solving, analytical thinking, and research skills • Aptitude for detail with the ability to work in a team environment • Ability to identify tasks and take initiative with minimal direction • Experience with Windows O/S, Microsoft office (Word, Excel, Powerpoint, Visio) • Experience with Linux • Experience with C++ and Python programming languages Desirable Skills & Experience • Experience in the subsea industry • Experience with robotic systems • Control Systems: theory & practice • Labview and Arduino programming • MATLAB and Simulink experience • ISO9001 quality control • Extracurricular club/team involvement Please include a cover letter as part of your application. Reports to: Software Engineering Manager Application advice: Well written cover letters carry a lot of weight, as do select photos of projects and/or experience. What makes you unique, special & interesting to us? Don’t tell us – show us! The above job requirements will be further developed during the term. All requirements are not needed to apply, but some experience will be helpful.
#include "Sorter.hpp" #include <iostream> #include <algorithm> #include <iomanip> #include <cmath> #include <regex> using namespace std; // Constructor Sorter::Sorter() { initializeRelatedSkills(); } // Initialize related skills mapping void Sorter::initializeRelatedSkills() const { // Programming languages family relatedSkills["Python"] = {"python", "python3", "python programming", "django", "flask"}; relatedSkills["Java"] = {"java", "java8", "java11", "spring", "maven", "gradle"}; relatedSkills["C++"] = {"cpp", "c plus plus", "c/c++", "embedded"}; relatedSkills["JavaScript"] = {"js", "javascript", "node.js", "react", "vue", "angular", "typescript"}; relatedSkills["SQL"] = {"sql", "mysql", "postgresql", "database", "query"}; // Web frameworks relatedSkills["React"] = {"react", "reactjs", "react.js", "jsx"}; relatedSkills["Node.js"] = {"node", "nodejs", "node.js", "express"}; // GIS family relatedSkills["ArcGIS"] = {"arcgis", "esri", "gis", "mapping", "arcmap"}; relatedSkills["GIS"] = {"gis", "mapping", "spatial", "geographic"}; // Data science relatedSkills["Machine Learning"] = {"ml", "machine learning", "ai", "artificial intelligence", "deep learning"}; relatedSkills["Data Analysis"] = {"data analysis", "analytics", "statistics", "visualization"}; } // Convert string to lowercase string Sorter::toLower(const string& str) const { string lower = str; transform(lower.begin(), lower.end(), lower.begin(), ::tolower); return lower; } // Check for exact word match bool Sorter::isExactMatch(const string& text, const string& keyword) const { string lowerText = toLower(text); string lowerKeyword = toLower(keyword); regex wordRegex("\\b" + lowerKeyword + "\\b"); return regex_search(lowerText, wordRegex); } // Check for partial match bool Sorter::isPartialMatch(const string& text, const string& keyword) const { string lowerText = toLower(text); string lowerKeyword = toLower(keyword); return lowerText.find(lowerKeyword) != string::npos; } // Calculate similarity between two strings (0-1) double Sorter::calculateSimilarity(const string& s1, const string& s2) const { string lower1 = toLower(s1); string lower2 = toLower(s2); if (lower1 == lower2) return 1.0; // Check if one contains the other if (lower1.find(lower2) != string::npos || lower2.find(lower1) != string::npos) { return 0.8; } // Simple character overlap (very basic) int common = 0; for (char c : lower1) { if (lower2.find(c) != string::npos) { common++; } } double maxLen = max(lower1.length(), lower2.length()); return (maxLen > 0) ? (common / maxLen) * 0.5 : 0.0; } // Check if two skills are related bool Sorter::areSkillsRelated(const string& skill1, const string& skill2) const { string lower1 = toLower(skill1); string lower2 = toLower(skill2); // Direct relationship for (const auto& [baseSkill, relatedList] : relatedSkills) { string lowerBase = toLower(baseSkill); // Check if either skill is the base if (lower1 == lowerBase || lower2 == lowerBase) { for (const auto& related : relatedList) { string lowerRelated = toLower(related); if (lower1 == lowerRelated || lower2 == lowerRelated) { return true; } } } // Check if both are in the same related list bool skill1InList = false; bool skill2InList = false; for (const auto& related : relatedList) { string lowerRelated = toLower(related); if (lower1 == lowerRelated) skill1InList = true; if (lower2 == lowerRelated) skill2InList = true; } if (skill1InList && skill2InList) { return true; } } // Partial match as fallback if (lower1.find(lower2) != string::npos || lower2.find(lower1) != string::npos) { return true; } return false; } // Get match value between student skill and job skill (0-1) double Sorter::getSkillMatchValue(const string& studentSkill, const string& jobSkill) const { string lowerStudent = toLower(studentSkill); string lowerJob = toLower(jobSkill); // Exact match if (lowerStudent == lowerJob) { return 1.0; } // Related skills if (areSkillsRelated(studentSkill, jobSkill)) { return 0.7; } // Partial match if (lowerStudent.find(lowerJob) != string::npos || lowerJob.find(lowerStudent) != string::npos) { return 0.5; } return 0.0; } // Helper function to extract potential skills from text descriptions vector<string> Sorter::extractSkillsFromText(const string& text, const vector<string>& jobSkills) const { vector<string> foundSkills; string lowerText = toLower(text); for (const auto& jobSkill : jobSkills) { string lowerSkill = toLower(jobSkill); // Check if the job skill appears in the text if (lowerText.find(lowerSkill) != string::npos) { foundSkills.push_back(jobSkill); } // Also check related skills else { for (const auto& [baseSkill, relatedList] : relatedSkills) { if (lowerSkill == toLower(baseSkill)) { for (const auto& related : relatedList) { if (lowerText.find(toLower(related)) != string::npos) { foundSkills.push_back(jobSkill); break; } } } } } } return foundSkills; } // Updated calculateSkillScore function double Sorter::calculateSkillScore(const Job& job, const StudentProfile& student) const { const auto& jobSkills = job.getRequiredSkills(); const auto& studentSkills = student.getSkills(); const auto& studentProjects = student.getProjects(); const auto& studentCourses = student.getCourses(); if (jobSkills.empty()) { return 0.5; // Neutral score if no skills listed } // Step 1: Create a map to track which job skills are covered map<string, double> skillCoverage; for (const auto& jobSkill : jobSkills) { skillCoverage[jobSkill] = 0.0; // Initialize with no coverage } // Step 2: Check explicitly listed skills (highest confidence) for (const auto& studentSkill : studentSkills) { for (const auto& jobSkill : jobSkills) { double matchValue = getSkillMatchValue(studentSkill, jobSkill); if (matchValue > skillCoverage[jobSkill]) { skillCoverage[jobSkill] = max(skillCoverage[jobSkill], matchValue); } } } // Step 3: Extract skills from projects (medium confidence) for (const auto& project : studentProjects) { vector<string> extractedSkills = extractSkillsFromText(project, jobSkills); for (const auto& skill : extractedSkills) { // Project evidence gives 0.8 confidence (slightly less than explicit skill) skillCoverage[skill] = max(skillCoverage[skill], 0.8); } } // Step 4: Extract skills from courses (medium-high confidence) for (const auto& course : studentCourses) { vector<string> extractedSkills = extractSkillsFromText(course, jobSkills); for (const auto& skill : extractedSkills) { // Course evidence gives 0.9 confidence (almost as good as explicit skill) skillCoverage[skill] = max(skillCoverage[skill], 0.9); } } // Step 5: Calculate overall skill score double totalCoverage = 0.0; for (const auto& [skill, coverage] : skillCoverage) { totalCoverage += coverage; } // Base score is average coverage of required skills double baseScore = totalCoverage / jobSkills.size(); // Bonus for having multiple ways to demonstrate skills int skillsCovered = 0; for (const auto& [skill, coverage] : skillCoverage) { if (coverage > 0.5) skillsCovered++; } double coverageRatio = skillsCovered / (double)jobSkills.size(); // Final score combines depth (coverage) and breadth (how many skills covered) double finalScore = (baseScore * 0.7) + (coverageRatio * 0.3); return min(1.0, finalScore); // Cap at 1.0 } // Calculate interest score double Sorter::calculateInterestScore(const Job& job, const StudentProfile& student) const { const auto& interests = student.getInterests(); const auto& jobSkills = job.getRequiredSkills(); const auto& industries = job.getIndustries(); const string& major = student.getMajor(); // GET MAJOR if (interests.empty() && major.empty()) { return 0.5; } double totalScore = 0.0; int matchedItems = 0; // Check interests (as before) for (const auto& interest : interests) { double bestMatch = 0.0; // ... existing interest matching code ... if (bestMatch > 0) { totalScore += bestMatch; matchedItems++; } } // NEW: Check major against job title and industry if (!major.empty()) { double majorMatch = 0.0; // Check against job title if (isPartialMatch(job.getTitle(), major)) { majorMatch = max(majorMatch, 0.7); } // Check against industries for (const auto& industry : industries) { if (isPartialMatch(industry, major)) { majorMatch = max(majorMatch, 0.8); } } // Check against skills for (const auto& skill : jobSkills) { if (isPartialMatch(skill, major)) { majorMatch = max(majorMatch, 0.6); } } if (majorMatch > 0) { totalScore += majorMatch; matchedItems++; } } return (matchedItems > 0) ? totalScore / matchedItems : 0.0; } // Calculate industry match score double Sorter::calculateIndustryScore(const Job& job, const StudentProfile& student) const { const auto& industries = job.getIndustries(); const auto& interests = student.getInterests(); const auto& experiences = student.getExperiences(); if (industries.empty()) { return 0.5; // Neutral if no industries listed } double totalScore = 0.0; // Check if student's experiences match industries for (const auto& industry : industries) { double bestMatch = 0.0; // Match with experiences for (const auto& exp : experiences) { if (isPartialMatch(exp, industry)) { bestMatch = max(bestMatch, 1.0); } } // Also consider interests as secondary indicator for (const auto& interest : interests) { if (isPartialMatch(industry, interest)) { bestMatch = max(bestMatch, 0.6); // Interest alone is worth less than actual experience } } totalScore += bestMatch; } return totalScore / industries.size(); } // Calculate remote match score double Sorter::calculateRemoteScore(const Job& job, const StudentProfile& student) const { bool studentWantsRemote = student.getWantRemote(); bool jobIsRemote = job.getRemote(); // Student wants remote AND job is remote = PERFECT match if (studentWantsRemote && jobIsRemote) { return 1.0; // 100% - exactly what they want } // Student wants remote but job is onsite = POOR match if (studentWantsRemote && !jobIsRemote) { return 0.2; // 20% - not what they wanted } // Student wants onsite but job is remote = POOR match if (!studentWantsRemote && jobIsRemote) { return 0.2; // 20% - not what they wanted } // Student wants onsite AND job is onsite = PERFECT match if (!studentWantsRemote && !jobIsRemote) { return 1.0; // 100% - exactly what they want } return 0.5; // Neutral fallback } // Calculate total score for a job double Sorter::calculateTotalScore(const Job& job, const StudentProfile& student) const { // Check degree level FIRST - GATEKEEPER string jobExp = toLower(job.getExperienceLevel()); if (jobExp == "phd" || jobExp == "masters") { return 0.0; // Not qualified - score 0 } // Only calculate detailed scores for undergraduate positions double skillScore = calculateSkillScore(job, student); double interestScore = calculateInterestScore(job, student); double remoteScore = calculateRemoteScore(job, student); double industryScore = calculateIndustryScore(job, student); // Apply weights (now with 4 components) double total = (skillScore * weights.skills) + (interestScore * weights.interests) + (remoteScore * weights.remote) + (industryScore * weights.industry); // Normalize to percentage double maxPossible = weights.skills + weights.interests + weights.remote + weights.industry; return (total / maxPossible) * 100.0; } // Sort jobs by score vector<pair<Job, double>> Sorter::sortJobs(const vector<Job>& jobs, const StudentProfile& student) const { vector<pair<Job, double>> ranked; for (const auto& job : jobs) { double score = calculateTotalScore(job, student); ranked.push_back({job, score}); } // Sort by score (highest first) sort(ranked.begin(), ranked.end(), [](const pair<Job, double>& a, const pair<Job, double>& b) { return a.second > b.second; }); return ranked; } // Get detailed breakdown of match scores map<string, double> Sorter::getMatchBreakdown(const Job& job, const StudentProfile& student) const { map<string, double> breakdown; breakdown["Skills"] = calculateSkillScore(job, student) * 100; breakdown["Interests"] = calculateInterestScore(job, student) * 100; breakdown["Remote"] = calculateRemoteScore(job, student) * 100; breakdown["Industry"] = calculateIndustryScore(job, student) * 100; return breakdown; } // Helper function for getting matched skills vector<string> Sorter::getMatchedSkills(const Job& job, const StudentProfile& student) const { const auto& jobSkills = job.getRequiredSkills(); const auto& studentSkills = student.getSkills(); vector<string> matchedSkills; for (const auto& jobSkill : jobSkills) { for (const auto& studentSkill : studentSkills) { if (getSkillMatchValue(studentSkill, jobSkill) >= 0.5) { matchedSkills.push_back(jobSkill); break; } } } return matchedSkills; } void Sorter::displayRankings(const vector<pair<Job, double>>& rankedJobs, const StudentProfile& student) const { cout << "\n" << string(80, '=') << "\n"; cout << " JOB RANKINGS FOR " << student.getName() << "\n"; cout << string(80, '=') << "\n\n"; if (rankedJobs.empty()) { cout << "No jobs to rank.\n"; return; } // Separate jobs by qualification vector<pair<Job, double>> qualified; vector<pair<Job, double>> unqualified; for (const auto& jobPair : rankedJobs) { string jobExp = toLower(jobPair.first.getExperienceLevel()); if (jobExp == "phd" || jobExp == "masters") { unqualified.push_back(jobPair); } else { qualified.push_back(jobPair); } } // Display qualified jobs first if (!qualified.empty()) { cout << "JOBS YOU QUALIFY FOR:\n"; cout << string(80, '-') << "\n"; for (size_t i = 0; i < qualified.size(); ++i) { const auto& job = qualified[i].first; double score = qualified[i].second; auto breakdown = getMatchBreakdown(job, student); cout << "+" << string(78, '-') << "+\n"; cout << "| RANK #" << left << setw(3) << (i + 1) << " - " << setw(50) << job.getTitle() << " Score: " << fixed << setprecision(1) << score << "% |\n"; cout << "|" << string(78, '-') << "|\n"; cout << "| Company: " << left << setw(68) << job.getCompany() << "|\n"; cout << "| Type (Remote/Onsite): " << left << setw(27) << (job.getRemote() ? "Yes" : "No") << " Salary: $" << fixed << setprecision(2) << job.getSalary() << " |\n"; cout << "|" << string(78, '-') << "|\n"; // Show match breakdown cout << "| MATCH BREAKDOWN: |\n"; cout << "| Skills: " << fixed << setprecision(1) << setw(6) << breakdown["Skills"] << "% match" << string(44 - to_string((int)breakdown["Skills"]).length(), ' ') << "|\n"; cout << "| Interests: " << fixed << setprecision(1) << setw(6) << breakdown["Interests"] << "% match" << string(44 - to_string((int)breakdown["Interests"]).length(), ' ') << "|\n"; cout << "| Industry: " << fixed << setprecision(1) << setw(6) << breakdown["Industry"] << "% match" << string(44 - to_string((int)breakdown["Industry"]).length(), ' ') << "|\n"; cout << "| Type (Remote/Onsite): " << fixed << setprecision(1) << setw(6) << breakdown["Remote"] << "% match" << string(44 - to_string((int)breakdown["Remote"]).length(), ' ') << "|\n"; cout << "|" << string(78, '-') << "|\n"; // Get all matches vector<string> matchedSkills = getMatchedSkills(job, student); vector<string> matchedIndustries; vector<string> matchedInterests; // Find matched industries const auto& jobIndustries = job.getIndustries(); const auto& studentExperiences = student.getExperiences(); const auto& studentInterests = student.getInterests(); // Check which industries match student experiences or interests for (const auto& industry : jobIndustries) { // Check experiences for (const auto& exp : studentExperiences) { if (isPartialMatch(exp, industry)) { matchedIndustries.push_back(industry + " (experience)"); break; } } // Check interests (if not already matched by experience) if (find(matchedIndustries.begin(), matchedIndustries.end(), industry + " (experience)") == matchedIndustries.end()) { for (const auto& interest : studentInterests) { if (isPartialMatch(interest, industry)) { matchedIndustries.push_back(industry + " (interest)"); break; } } } } // Find which interests matched for (const auto& interest : studentInterests) { // Check against job title if (isPartialMatch(job.getTitle(), interest)) { matchedInterests.push_back(interest + " (title)"); } // Check against job skills else { for (const auto& skill : job.getRequiredSkills()) { if (isPartialMatch(skill, interest) || isPartialMatch(interest, skill)) { matchedInterests.push_back(interest + " (skill)"); break; } } } } // Display Matched Skills if (!matchedSkills.empty()) { cout << "| MATCHED SKILLS: |\n"; string line = "| "; for (const auto& skill : matchedSkills) { if (line.length() + skill.length() + 3 > 79) { cout << line << string(79 - line.length(), ' ') << "|\n"; line = "| " + skill; } else { if (line != "| ") line += ", "; line += skill; } } if (!line.empty()) { cout << line << string(79 - line.length(), ' ') << "|\n"; } } // Display Matched Industries if (!matchedIndustries.empty()) { cout << "| MATCHED INDUSTRIES: |\n"; string line = "| "; for (const auto& industry : matchedIndustries) { if (line.length() + industry.length() + 3 > 79) { cout << line << string(79 - line.length(), ' ') << "|\n"; line = "| " + industry; } else { if (line != "| ") line += ", "; line += industry; } } if (!line.empty()) { cout << line << string(79 - line.length(), ' ') << "|\n"; } } // Display Matched Interests if (!matchedInterests.empty()) { cout << "| MATCHED INTERESTS: |\n"; string line = "| "; for (const auto& interest : matchedInterests) { if (line.length() + interest.length() + 3 > 79) { cout << line << string(79 - line.length(), ' ') << "|\n"; line = "| " + interest; } else { if (line != "| ") line += ", "; line += interest; } } if (!line.empty()) { cout << line << string(79 - line.length(), ' ') << "|\n"; } } // Show skills evidence from projects/courses (if any) const auto& projects = student.getProjects(); const auto& courses = student.getCourses(); if (!projects.empty() || !courses.empty()) { cout << "|" << string(78, '-') << "|\n"; cout << "| SKILLS EVIDENCE: |\n"; if (!projects.empty()) { cout << "| • From " << projects.size() << " project(s) |\n"; } if (!courses.empty()) { cout << "| • From " << courses.size() << " course(s) |\n"; } } cout << "+" << string(78, '-') << "+\n\n"; } } // Display unqualified jobs with warning if (!unqualified.empty()) { cout << "\nJOBS YOU ARE NOT QUALIFIED FOR (Advanced Degree Required):\n"; cout << string(80, '-') << "\n"; for (const auto& jobPair : unqualified) { const auto& job = jobPair.first; cout << "+" << string(78, '-') << "+\n"; cout << "| NOT QUALIFIED: " << left << setw(57) << job.getTitle() << " |\n"; cout << "|" << string(78, '-') << "|\n"; cout << "| Company: " << left << setw(68) << job.getCompany() << "|\n"; cout << "| This position requires a " << job.getExperienceLevel() << " degree. |\n"; cout << "| You are an undergraduate student. |\n"; // Still show what the score WOULD have been (for curiosity) auto breakdown = getMatchBreakdown(job, student); double potentialScore = (breakdown["Skills"] * weights.skills + breakdown["Interests"] * weights.interests + breakdown["Industry"] * weights.industry + breakdown["Remote"] * weights.remote) / (weights.skills + weights.interests + weights.industry + weights.remote); cout << "| Score would have been: " << fixed << setprecision(1) << setw(6) << potentialScore << "% (if qualified) |\n"; cout << "+" << string(78, '-') << "+\n\n"; } } } // Set custom weights void Sorter::setWeights(double skills, double interests, double remote, double industry) { double total = skills + interests + remote + industry; if (abs(total - 1.0) > 0.01) { cout << "Warning: Weights sum to " << total << ". Normalizing to 1.0\n"; weights.skills = skills / total; weights.interests = interests / total; weights.remote = remote / total; weights.industry = industry / total; } else { weights.skills = skills; weights.interests = interests; weights.remote = remote; weights.industry = industry; } } // Reset to default weights void Sorter::resetWeights() { weights.skills = 0.50; weights.interests = 0.15; weights.remote = 0.10; weights.industry = 0.25; }
#include "JobParser.hpp" #include <iostream> #include <sstream> #include <algorithm> #include <cctype> #include <regex> #include <set> using namespace std; // Constructor JobParser::JobParser(const string& file) : filename(file) {} // Helper: trim whitespace string JobParser::trim(const string& str) { size_t first = str.find_first_not_of(" \t\n\r"); if (first == string::npos) return ""; size_t last = str.find_last_not_of(" \t\n\r"); return str.substr(first, last - first + 1); } // Helper: split string by delimiter vector<string> JobParser::splitString(const string& str, char delimiter) { vector<string> tokens; stringstream ss(str); string token; while (getline(ss, token, delimiter)) { tokens.push_back(trim(token)); } return tokens; } // Helper: check if text contains a word (case-insensitive, whole word) bool JobParser::containsWord(const string& text, const string& word) { string lowerText = text; string lowerWord = word; transform(lowerText.begin(), lowerText.end(), lowerText.begin(), ::tolower); transform(lowerWord.begin(), lowerWord.end(), lowerWord.begin(), ::tolower); regex wordRegex("\\b" + lowerWord + "\\b"); return regex_search(lowerText, wordRegex); } // Helper: extract salary from description double JobParser::extractSalary(const string& text) { // Pattern for salary ranges: $24.80-$27.33/hr or $24.80 per hour regex rangePattern(R"(\$\s*(\d+(?:\.\d+)?)\s*-\s*\$\s*(\d+(?:\.\d+)?)\s*(?:\/hr|per hour|/hour|/year|annually)?)"); regex singlePattern(R"(\$\s*(\d+(?:\.\d+)?)\s*(?:\/hr|per hour|/hour|/year|annually))"); regex numberPattern(R"((\d+(?:\.\d+)?)\s*(?:\/hr|per hour|/hour))"); smatch matches; string lowerText = text; transform(lowerText.begin(), lowerText.end(), lowerText.begin(), ::tolower); if (regex_search(lowerText, matches, rangePattern)) { return stod(matches[1].str()); } if (regex_search(lowerText, matches, singlePattern)) { return stod(matches[1].str()); } if (regex_search(lowerText, matches, numberPattern)) { return stod(matches[1].str()); } return 0.0; } // Helper: determine experience level from description string JobParser::determineExperienceLevel(const string& text) { string lowerText = text; transform(lowerText.begin(), lowerText.end(), lowerText.begin(), ::tolower); if (containsWord(lowerText, "phd") || containsWord(lowerText, "doctoral") || containsWord(lowerText, "doctorate") || containsWord(lowerText, "ph.d")) { return "phd"; } if (containsWord(lowerText, "masters") || containsWord(lowerText, "master's") || containsWord(lowerText, "graduate degree") || containsWord(lowerText, "graduate student") || containsWord(lowerText, "msc") || containsWord(lowerText, "m.s.")) { return "masters"; } if (containsWord(lowerText, "undergraduate") || containsWord(lowerText, "bachelor") || containsWord(lowerText, "bsc") || containsWord(lowerText, "b.s.") || containsWord(lowerText, "b.a.") || containsWord(lowerText, "co-op") || containsWord(lowerText, "coop") || containsWord(lowerText, "intern") || containsWord(lowerText, "internship")) { return "undergraduate"; } return "undergraduate"; } // Helper: extract ALL skills from description (comprehensive list) vector<string> JobParser::extractAllSkills(const string& text) { set<string> uniqueSkills; string lowerText = text; transform(lowerText.begin(), lowerText.end(), lowerText.begin(), ::tolower); // ===== PROGRAMMING LANGUAGES ===== vector<pair<string, string>> programmingLanguages = { {"python", "Python"}, {"java", "Java"}, {"c\\+\\+", "C++"}, {"c#", "C#"}, {"javascript", "JavaScript"}, {"typescript", "TypeScript"}, {"html", "HTML"}, {"css", "CSS"}, {"sql", "SQL"}, {"php", "PHP"}, {"ruby", "Ruby"}, {"swift", "Swift"}, {"kotlin", "Kotlin"}, {"go", "Go"}, {"rust", "Rust"}, {"scala", "Scala"}, {"perl", "Perl"}, {"r\\b", "R"}, {"matlab", "MATLAB"}, {"julia", "Julia"}, {"dart", "Dart"}, {"assembly", "Assembly"}, {"bash", "Bash"}, {"powershell", "PowerShell"} }; // ===== WEB DEVELOPMENT ===== vector<pair<string, string>> webTechnologies = { {"react", "React"}, {"angular", "Angular"}, {"vue", "Vue.js"}, {"node.js", "Node.js"}, {"nodejs", "Node.js"}, {"express", "Express.js"}, {"django", "Django"}, {"flask", "Flask"}, {"spring", "Spring"}, {"asp.net", "ASP.NET"}, {"jquery", "jQuery"}, {"bootstrap", "Bootstrap"}, {"tailwind", "Tailwind CSS"}, {"rest", "REST API"}, {"graphql", "GraphQL"}, {"ajax", "AJAX"}, {"json", "JSON"}, {"xml", "XML"}, {"webpack", "Webpack"}, {"babel", "Babel"}, {"npm", "npm"}, {"yarn", "Yarn"} }; // ===== DATABASES ===== vector<pair<string, string>> databases = { {"mysql", "MySQL"}, {"postgresql", "PostgreSQL"}, {"postgres", "PostgreSQL"}, {"mongodb", "MongoDB"}, {"nosql", "NoSQL"}, {"redis", "Redis"}, {"elasticsearch", "Elasticsearch"}, {"cassandra", "Cassandra"}, {"oracle", "Oracle"}, {"sqlite", "SQLite"}, {"mariadb", "MariaDB"}, {"dynamodb", "DynamoDB"}, {"firebase", "Firebase"}, {"supabase", "Supabase"} }; // ===== CLOUD & DEVOPS ===== vector<pair<string, string>> cloudDevOps = { {"aws", "AWS"}, {"amazon web services", "AWS"}, {"azure", "Azure"}, {"gcp", "Google Cloud"}, {"google cloud", "Google Cloud"}, {"cloud computing", "Cloud Computing"}, {"docker", "Docker"}, {"kubernetes", "Kubernetes"}, {"k8s", "Kubernetes"}, {"jenkins", "Jenkins"}, {"gitlab ci", "GitLab CI"}, {"github actions", "GitHub Actions"}, {"terraform", "Terraform"}, {"ansible", "Ansible"}, {"puppet", "Puppet"}, {"chef", "Chef"}, {"linux", "Linux"}, {"unix", "Unix"}, {"windows server", "Windows Server"} }; // ===== GIS & ENGINEERING ===== vector<pair<string, string>> gisEngineering = { {"arcgis", "ArcGIS"}, {"arcgis pro", "ArcGIS Pro"}, {"vertigis", "Vertigis Studio"}, {"fme", "FME"}, {"esri", "ESRI"}, {"gis", "GIS"}, {"qgis", "QGIS"}, {"mapbox", "Mapbox"}, {"google earth", "Google Earth"}, {"remote sensing", "Remote Sensing"}, {"autocad", "AutoCAD"}, {"solidworks", "SolidWorks"}, {"catia", "CATIA"}, {"ansys", "ANSYS"}, {"matlab", "MATLAB"}, {"simulink", "Simulink"}, {"labview", "LabVIEW"}, {"plc", "PLC"}, {"scada", "SCADA"}, {"drainage", "Drainage Engineering"}, {"infrastructure", "Infrastructure"}, {"transportation", "Transportation Engineering"} }; // ===== DATA SCIENCE & ML ===== vector<pair<string, string>> dataScience = { {"machine learning", "Machine Learning"}, {"deep learning", "Deep Learning"}, {"ai", "Artificial Intelligence"}, {"artificial intelligence", "Artificial Intelligence"}, {"data science", "Data Science"}, {"data analysis", "Data Analysis"}, {"data visualization", "Data Visualization"}, {"statistics", "Statistics"}, {"pandas", "Pandas"}, {"numpy", "NumPy"}, {"scikit-learn", "Scikit-learn"}, {"tensorflow", "TensorFlow"}, {"pytorch", "PyTorch"}, {"keras", "Keras"}, {"opencv", "OpenCV"}, {"nlp", "Natural Language Processing"}, {"llm", "Large Language Models"}, {"chatgpt", "ChatGPT"}, {"prompt engineering", "Prompt Engineering"}, {"tableau", "Tableau"}, {"power bi", "Power BI"}, {"excel", "Excel"}, {"spss", "SPSS"}, {"sas", "SAS"} }; // ===== SOFT SKILLS ===== vector<pair<string, string>> softSkills = { {"leadership", "Leadership"}, {"communication", "Communication"}, {"teamwork", "Teamwork"}, {"collaboration", "Collaboration"}, {"problem solving", "Problem Solving"}, {"critical thinking", "Critical Thinking"}, {"time management", "Time Management"}, {"project management", "Project Management"}, {"agile", "Agile"}, {"scrum", "Scrum"}, {"kanban", "Kanban"}, {"presentation", "Presentation Skills"}, {"writing", "Technical Writing"}, {"documentation", "Documentation"} }; // Combine all skill categories vector<pair<string, string>> allSkills; allSkills.insert(allSkills.end(), programmingLanguages.begin(), programmingLanguages.end()); allSkills.insert(allSkills.end(), webTechnologies.begin(), webTechnologies.end()); allSkills.insert(allSkills.end(), databases.begin(), databases.end()); allSkills.insert(allSkills.end(), cloudDevOps.begin(), cloudDevOps.end()); allSkills.insert(allSkills.end(), gisEngineering.begin(), gisEngineering.end()); allSkills.insert(allSkills.end(), dataScience.begin(), dataScience.end()); allSkills.insert(allSkills.end(), softSkills.begin(), softSkills.end()); for (const auto& skillPair : allSkills) { const string& pattern = skillPair.first; const string& displayName = skillPair.second; regex wordRegex("\\b" + pattern + "\\b", regex::icase); if (regex_search(lowerText, wordRegex)) { uniqueSkills.insert(displayName); } } vector<string> skills(uniqueSkills.begin(), uniqueSkills.end()); return skills; } // Helper: extract industries from description vector<string> JobParser::extractIndustries(const string& text) { set<string> uniqueIndustries; string lowerText = text; transform(lowerText.begin(), lowerText.end(), lowerText.begin(), ::tolower); vector<pair<string, string>> industryKeywords = { {"technology", "Technology"}, {"software", "Software"}, {"hardware", "Hardware"}, {"healthcare", "Healthcare"}, {"medical", "Healthcare"}, {"pharma", "Pharmaceutical"}, {"biotech", "Biotechnology"}, {"finance", "Finance"}, {"banking", "Finance"}, {"insurance", "Insurance"}, {"aerospace", "Aerospace"}, {"aviation", "Aviation"}, {"automotive", "Automotive"}, {"energy", "Energy"}, {"oil and gas", "Oil & Gas"}, {"renewable energy", "Renewable Energy"}, {"consulting", "Consulting"}, {"education", "Education"}, {"university", "Education"}, {"government", "Government"}, {"public sector", "Government"}, {"non-profit", "Non-profit"}, {"ngo", "Non-profit"}, {"retail", "Retail"}, {"e-commerce", "E-commerce"}, {"manufacturing", "Manufacturing"}, {"telecommunications", "Telecommunications"}, {"telecom", "Telecommunications"}, {"transportation", "Transportation"}, {"logistics", "Logistics"}, {"infrastructure", "Infrastructure"}, {"construction", "Construction"}, {"real estate", "Real Estate"}, {"sustainability", "Sustainability"}, {"climate", "Climate Tech"}, {"environmental", "Environmental"}, {"mining", "Mining"}, {"agriculture", "Agriculture"}, {"food", "Food & Beverage"}, {"hospitality", "Hospitality"}, {"tourism", "Tourism"}, {"media", "Media"}, {"entertainment", "Entertainment"}, {"gaming", "Gaming"}, {"cybersecurity", "Cybersecurity"}, {"defense", "Defense"} }; for (const auto& industryPair : industryKeywords) { const string& pattern = industryPair.first; const string& displayName = industryPair.second; regex wordRegex("\\b" + pattern + "\\b", regex::icase); if (regex_search(lowerText, wordRegex)) { uniqueIndustries.insert(displayName); } } vector<string> industries(uniqueIndustries.begin(), uniqueIndustries.end()); return industries; } // NEW: Extract title from "Title:" prefix string JobParser::extractTitle(const string& text) { stringstream ss(text); string line; while (getline(ss, line)) { if (line.find("Title:") == 0) { return trim(line.substr(6)); // Return everything after "Title:" } } return "Unknown Title"; // Default if not found } // NEW: Extract company from "Company:" prefix string JobParser::extractCompany(const string& text) { stringstream ss(text); string line; while (getline(ss, line)) { if (line.find("Company:") == 0) { return trim(line.substr(8)); // Return everything after "Company:" } } return "Unknown Company"; // Default if not found } // Main parsing method vector<Job> JobParser::loadAllJobs() { vector<Job> jobs; ifstream file(filename); if (!file.is_open()) { cout << "Error: Could not open " << filename << endl; return jobs; } string line; string currentDescription; bool readingJob = false; int jobCount = 0; while (getline(file, line)) { // Check for job separator (---) if (line.find("---") == 0) { if (readingJob && !currentDescription.empty()) { jobCount++; // Create and populate job Job job; // Extract title and company from description using prefixes job.setTitle(extractTitle(currentDescription)); job.setCompany(extractCompany(currentDescription)); // Extract ALL skills from description job.setJobSkills(extractAllSkills(currentDescription)); // Extract other fields job.setExperienceLevel(determineExperienceLevel(currentDescription)); job.setRemote(containsWord(currentDescription, "remote")); job.setSalary(extractSalary(currentDescription)); job.setIndustries(extractIndustries(currentDescription)); jobs.push_back(job); cout << "Parsed job #" << jobCount << ": " << job.getTitle() << " (" << job.getRequiredSkills().size() << " skills found)\n"; } // Reset for next job currentDescription.clear(); readingJob = false; } else { // Add line to current job description if (!readingJob && !line.empty()) { readingJob = true; } if (readingJob) { currentDescription += line + "\n"; } } } // Don't forget the last job if (readingJob && !currentDescription.empty()) { jobCount++; Job job; job.setTitle(extractTitle(currentDescription)); job.setCompany(extractCompany(currentDescription)); job.setJobSkills(extractAllSkills(currentDescription)); job.setExperienceLevel(determineExperienceLevel(currentDescription)); job.setRemote(containsWord(currentDescription, "remote")); job.setSalary(extractSalary(currentDescription)); job.setIndustries(extractIndustries(currentDescription)); jobs.push_back(job); cout << "Parsed job #" << jobCount << ": " << job.getTitle() << " (" << job.getRequiredSkills().size() << " skills found)\n"; } file.close(); cout << "\nLoaded " << jobs.size() << " jobs from " << filename << endl; return jobs; } // Display parsed jobs for debugging void JobParser::displayParsedJobs(const vector<Job>& jobs) { for (size_t i = 0; i < jobs.size(); ++i) { const auto& job = jobs[i]; cout << "\n" << string(60, '=') << "\n"; cout << "JOB #" << (i + 1) << "\n"; cout << string(60, '=') << "\n"; cout << "Title: " << job.getTitle() << "\n"; cout << "Company: " << job.getCompany() << "\n"; cout << "Experience Level: " << job.getExperienceLevel() << "\n"; cout << "Remote: " << (job.getRemote() ? "Yes" : "No") << "\n"; cout << "Salary: $" << job.getSalary() << "\n"; cout << "Skills (" << job.getRequiredSkills().size() << " found):\n"; if (job.getRequiredSkills().empty()) { cout << " None detected\n"; } else { for (const auto& skill : job.getRequiredSkills()) { cout << " • " << skill << "\n"; } } cout << "Industries (" << job.getIndustries().size() << "):\n"; if (job.getIndustries().empty()) { cout << " None detected\n"; } else { for (const auto& industry : job.getIndustries()) { cout << " • " << industry << "\n"; } } cout << string(60, '-') << "\n"; } }
#ifndef JOB_PARSER_HPP #define JOB_PARSER_HPP #include <string> #include <vector> #include <fstream> #include "Job.hpp" using namespace std; class JobParser { private: string filename; // Helper methods vector<string> splitString(const string& str, char delimiter); string trim(const string& str); bool containsWord(const string& text, const string& word); double extractSalary(const string& text); string determineExperienceLevel(const string& text); vector<string> extractAllSkills(const string& text); // Extracts ALL skills found vector<string> extractIndustries(const string& text); string extractTitle(const string& text); string extractCompany(const string& text); public: // Constructor JobParser(const string& file); // Main parsing method vector<Job> loadAllJobs(); // For debugging void displayParsedJobs(const vector<Job>& jobs); }; #endif
#ifndef SORTER_HPP #define SORTER_HPP #include <vector> #include <utility> #include <string> #include <map> #include "Job.hpp" #include "StudentProfile.hpp" using namespace std; class Sorter { private: // Weights for different factors struct Weights { double skills = 0.50; // 50% - technical match double interests = 0.15; // 15% - interest alignment double remote = 0.10; // 10% - remote preference double industry = 0.25; // 25% - industry experience match } weights; // Helper methods for string matching string toLower(const string& str) const; bool isExactMatch(const string& text, const string& keyword) const; bool isPartialMatch(const string& text, const string& keyword) const; double calculateSimilarity(const string& s1, const string& s2) const; // Scoring helpers double calculateSkillScore(const Job& job, const StudentProfile& student) const; double calculateInterestScore(const Job& job, const StudentProfile& student) const; double calculateRemoteScore(const Job& job, const StudentProfile& student) const; double calculateIndustryScore(const Job& job, const StudentProfile& student) const; // Relationship mapping for related skills bool areSkillsRelated(const string& skill1, const string& skill2) const; double getSkillMatchValue(const string& studentSkill, const string& jobSkill) const; // Predefined skill relationships mutable map<string, vector<string>> relatedSkills; void initializeRelatedSkills() const; // Helper to get matched skills vector<string> getMatchedSkills(const Job& job, const StudentProfile& student) const; // Helper to extract skills from text descriptions vector<string> extractSkillsFromText(const string& text, const vector<string>& jobSkills) const; public: // Constructor Sorter(); // Main scoring method double calculateTotalScore(const Job& job, const StudentProfile& student) const; // Ranking methods vector<pair<Job, double>> sortJobs(const vector<Job>& jobs, const StudentProfile& student) const; // Display methods void displayRankings(const vector<pair<Job, double>>& rankedJobs, const StudentProfile& student) const; // Weight adjustment void setWeights(double skills, double interests, double remote, double industry); void resetWeights(); // Get match breakdown for a single job map<string, double> getMatchBreakdown(const Job& job, const StudentProfile& student) const; }; #endif

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue