diff --git a/Capstone2.3.gs b/Capstone2.3.gs new file mode 100644 index 0000000..a81bfd2 --- /dev/null +++ b/Capstone2.3.gs @@ -0,0 +1,508 @@ +/* THINGS THAT STILL NEED TO BE DONE +- Time in case lunch goes until 1:00PM, probably need to change it to military time +- Change the whitespace around the strings so that we can get rid of the accidential click problem +- Merge functions that can be merged to make runtime much faster +*/ + + +/* +- FIRST VERSION OF ELIGIBILITY MATCHING - +In this version we just do a basic eligibility matching, where if mentors say they can be carpooled, +we match them with schools where you need a car to get there on time. +This version now has the added the function where we see the matches with what time,day, and school they would go to meet the mentee. +Reminders: (write all weird errors below that relate to code) +- if you get a -1.0 when you think you shouldn't, you have probably added a space. +*/ + +// CLASSES +var Mentor = function(name, gender, language, transport, transport_check, mon_t, tues_t, weds_t, thurs_t, fri_t){ + this.name = name; + this.gender = gender; + this.language = language; + this.transport = transport; + this.can_drive = transport_check; + this.monday_times = mon_t; + this.tuesday_times = tues_t; + this.wednesday_times = weds_t; + this.thursday_times = thurs_t; + this.friday_times = fri_t; + this.matches = []; + + this.addMatch = function(person){ + var temp_list = this.matches; + temp_list.push(person); + this.matches = temp_list; + } +} + +var Mentee = function(name, gender, language, transport, school, time){ + this.name = name; + this.gender = gender; + this.language = language; + this.transport = transport; + this.school = school; + this.time = time; +} + +// INITIALIZATION +var ss = SpreadsheetApp.getActiveSpreadsheet(); +var mentor_sheet = ss.getSheetByName("Mentor Information Sheet"); +var mentee_sheet = ss.getSheetByName("Mentee Information Sheet"); +var lunch_sheet = ss.getSheetByName("Lunch Times"); + + +// *************************************** MACROS ***************************************** +// TURNING SHEETS INTO DATASETS +var data_mentor = mentor_sheet.getDataRange().getValues(); +var mentor_dimensions = mentor_sheet.getDataRange(); +var data_mentee = mentee_sheet.getDataRange().getValues(); +var mentee_dimensions = mentee_sheet.getDataRange(); +var school_lunches = lunch_sheet.getDataRange().getValues(); +var lunches_dimensions = lunch_sheet.getDataRange(); + +for (var i = 0; i < data_mentor.length; i++){ + for (var j = 0; j < 30; j++){ + if (!(data_mentor[i][j] == undefined)){ + data_mentor[i][j] = data_mentor[i][j].toString().trim() + } + } +} + +for (var i = 0; i < data_mentee.length; i++){ + for (var j = 0; j < 30; j++){ + if (!(data_mentee[i][j] == undefined)){ + data_mentee[i][j] = data_mentee[i][j].toString().trim(); + } + } +} + +for (var i = 0; i < school_lunches.length; i++){ + for (var j = 0; j < 20; j++){ + if (!(school_lunches[i][j] == undefined)){ + school_lunches[i][j] = school_lunches[i][j].toString().trim(); + } + } +} + + +// TO ENSURE THAT THE COLUMNS WE'RE ACCESSING ARE THE ONES WE WANT TO ACCESS +var mentee_name_col = data_mentee[0].indexOf("Name of Student (First, Last)"); +var mentee_lang_col = data_mentee[0].indexOf("Does the student need a mentor that speaks Spanish?"); +var mentee_gender_col = data_mentee[0].indexOf("Gender"); +var mentee_transport = data_mentee[0].indexOf("School"); + +var mentor_name_col = data_mentor[0].indexOf("Name (First, Last)"); +var mentor_lang_col = data_mentor[0].indexOf("Do you speak Spanish?"); +var mentor_gender_col = data_mentor[0].indexOf("Gender"); +var mentor_transport = data_mentor[0].indexOf("Check ALL that apply"); + +var mon_times = data_mentor[0].indexOf("When are you free on Monday? (if you did not select Monday, please skip)"); +var tues_times = data_mentor[0].indexOf("When are you free on Tuesday? (if you did not select Tuesday, please skip)"); +var wed_times = data_mentor[0].indexOf("When are you free on Wednesday? (if you did not select Wednesday, please skip)"); +var thurs_times = data_mentor[0].indexOf("When are you free on Thursday? (if you did not select Thursday, please skip)"); +var fri_times = data_mentor[0].indexOf("When are you free on Friday? (if you did not select Friday, please skip)"); + +var grade_dict = {"Kindergarten": 1, "1st Grade": 2, "2nd Grade": 3, "3rd Grade": 4, "4th Grade": 5, "5th Grade": 6} +var school_col = data_mentee[0].indexOf("School"); +var grade_col = data_mentee[0].indexOf("Grade"); +var name_col = data_mentee[0].indexOf("Name of Student (First, Last)"); + +// ***************************************************************************************** + +// ALL DICTIONARIES WE WILL CONTINIOUSLY ACCESS + +// DICTIONARIES THAT STORE MENTOR PREFERENCES AND MENTEE PREFERENCES (Gender,Language,Transporation) +var mentor_prefs = {}; +var mentee_prefs = {}; + +// STUFF THAT CHARLIE ADDED +var mentees = []; +for(var i = 1; i < data_mentee.length; i++){ + mentees.push(data_mentee[i][mentee_name_col]); +} + +var prevMatch = []; +for (var i = 0; i < mentees.length; i++){ + prevMatch[i] = -1; +} + + +//MENTEE DICTIONARIES +var Mentee_Dict = {}; + +//MATCHES DICTIONARY +var matches = {}; + +// Mentor and Mentee Object Dictionaries +var Mentors = {}; +var Mentees = {}; + +//CREATED THIS LIST IN ORDER TO INDEX THROUGH ALL DICTIONARIES AT ONCE +var list_of_times = [mon_times, tues_times, wed_times, thurs_times, fri_times]; + + +function trim_whitespace(){ + for (var i = 0; i < data_mentor.length; i++){ + for (var j = 0; j < mentor_dimensions.length; j++){ + data_mentor[i][j] = data_mentor[i][j].trim(); + } + } + + for (var i = 0; i < data_mentee.length; i++){ + for (var j = 0; j < mentee_dimensions.length; j++){ + data_mentee[i][j] = data_mentee[i][j].trim(); + } + } + + for (var i = 0; i < school_lunches.length; i++){ + for (var j = 0; j < lunches_dimensions.length; j++){ + school_lunches[i][j] = school_lunches[i][j].trim(); + } + } +} + + +// CHECKS FOR GENDER, LANGUAGE, AND TRANSPORTATION +function check_preferences(){ + for (var i = 1; i < data_mentor.length; i++){ + var current_mentor = data_mentor[i]; + var mentor_name = data_mentor[i][mentor_name_col]; + var gender = ""; + var language = ""; + var transport; + + if (data_mentor[i][mentor_lang_col] == "Yes, I speak some Spanish."){ + language = "Yes"; + } + else{ + language = "No"; + } + + gender = data_mentor[i][mentor_gender_col]; + + var transportation_list = data_mentor[i][mentor_transport]; + + var has_transport = "No"; + transportation_list = transportation_list.split(","); + if (transportation_list.indexOf("I have a car and am willing to drive a carpool to my school") >= 0){ + transport = "Has car and is willing to drive a carpool"; + has_transport = "Yes"; + + } + else if (transportation_list.indexOf("I have a car and am willing to drive myself to my school") >= 0){ + transport = "Has car"; + has_transport = "Yes"; + } + else if (transportation_list.indexOf("I can ride in a carpool to get to my school") >= 0){ + transport = "Needs carpool unless biking or walking"; + has_transport = "Yes"; + if (transportation_list.indexOf("I have a bike and am willing to ride my bike to a school nearby")>=0){ + transport += ", has a bike or can walk"; + } + else{ + transport += ", doesn't have a bike but can walk"; + } + } + else{ + if (transportation_list.indexOf("I have a bike and am willing to ride my bike to a school nearby")>=0){ + transport = "Has a bike or can walk"; + } + else{ + transport = "Doesn't have a bike but can walk"; + } + } + + + var temp_dict = {}; + for (var day = 0; day < 5; day++){ + var current_time = list_of_times[day]; + var available = data_mentor[i][current_time]; + if (!(available == "")){ + available = available.replace(/\s/g, ''); + available = available.split(","); + var times_available = (connecting_times(convert_to_military(available))); + if (day == 0){ + temp_dict["Monday"] = times_available; + } + if (day == 1){ + temp_dict["Tuesday"] = times_available; + } + if (day == 2){ + temp_dict["Wednesday"] = times_available; + } + if (day == 3){ + temp_dict["Thursday"] = times_available; + } + if (day == 4){ + temp_dict["Friday"] = times_available; + } + } + } + + var mentor = new Mentor(mentor_name, gender, language, transport, has_transport, temp_dict["Monday"], temp_dict["Tuesday"], temp_dict["Wednesday"], temp_dict["Thursday"], temp_dict["Friday"]); + Mentors[mentor_name] = mentor; + } + + + for (var x = 1; x < data_mentee.length; x++){ + var mentee_name = data_mentee[x][mentee_name_col]; + var transportation = "No"; + var gender = data_mentee[x][mentee_gender_col]; + var language = data_mentee[x][mentee_lang_col]; + + if (data_mentee[x][mentee_transport] == "Berney" || + data_mentee[x][mentee_transport] == "Blue Ridge" || + data_mentee[x][mentee_transport] == "Prospect Point"){ + transportation = "Yes"; + } + + var school = data_mentee[x][mentee_transport]; + var mentee_school = data_mentee[x][school_col]; + var mentee_grade = data_mentee[x][grade_col]; + var time = [school_lunches[grade_dict[mentee_grade]][school_lunches[0].indexOf(mentee_school)]]; + + var mentee = new Mentee(mentee_name, gender, language, transportation, school, time); + Mentees[mentee_name] = mentee; + } +} + +// THIS FUNCTION REQUIRES THAT 1:00PM, 2:00PM, etc. comes after the earlier times in each list + +// https://stackoverflow.com/questions/29206453/best-way-to-convert-military-time-to-standard-time-in-javascript + +function convert_to_military(input_list){ + + for (var i = 0; i < (input_list.length); i++){ + var current_time = input_list[i]; + + var left_time = current_time.slice(0, current_time.indexOf("-")); + var left_converted_time = left_time; + var left_time = left_time.split(":"); + var left_hours = Number(left_time[0]); + + if (left_hours > 0 && left_hours <= 6){ + left_converted_time = ((12 + left_hours).toString() + ":" + left_time[1]); + } + + var right_time = current_time.slice((current_time.indexOf("-")+1)); + var right_converted_time = right_time; + var right_time = right_time.split(":"); + var right_hours = Number(right_time[0]); + + if (right_hours > 0 && right_hours <= 6){ + right_converted_time = ((12 + right_hours).toString() + ":" + right_time[1]); + } + + input_list[i] = left_converted_time + "-" + right_converted_time; + } + return input_list; +} + +// CONNECTING OVERLAPPING TIMES FOR MENTORS +function connecting_times(input_list){ + + var list_of_times = input_list; + //intitializing the start time + var first_item = list_of_times[0]; + var start_string = first_item.slice(0,first_item.indexOf("-")); + var new_list = []; + var marker = 0; + + for (var t = 0; t < (list_of_times.length-1); t++){ + // need to check for last time in list because of the way these comparisons are setup + var current_string = list_of_times[t]; + + //leftside comparison setup + var current_end_string = current_string.slice(6,11); + var left_comp = current_string.slice(6,8) + current_string.slice(9,11); + var left_numb = Number(left_comp); + + //rightside comparison setup + var next_string = list_of_times[t+1]; + var right_comp = next_string.slice(0,2) + next_string.slice(3,5); + var right_numb = Number(right_comp); + + if (right_numb > left_numb){ + new_list.push(start_string + "-" + current_end_string); + start_string = next_string.slice(0,first_item.indexOf("-")); + if (t == (list_of_times.length-2)){ + marker = 1} + } + + if ((t==list_of_times.length-2) && (marker == 0)){ + new_list.push(start_string + "-" + (next_string.slice(6,11))) + } + } + if (marker == 1){ + new_list.push(list_of_times[(list_of_times.length-1)]); + } + if (new_list && new_list.length){ + return new_list; + } +} + + +function time_to_value(input_list){ + if (input_list == undefined){ + return "empty"; + } + var temp_list = []; + for (var t= 0; t < input_list.length; t++){ + var current_time = input_list[t]; + var begin_time = current_time.slice(0,2) + current_time.slice(3,5); + begin_time = Number(begin_time); + var end_time = current_time.slice(6,8) + current_time.slice(9,11); + end_time = Number(end_time); + temp_list.push([begin_time, end_time]); + } + return temp_list; +} + +function compatability_check(mentor_times, mentee_times, mentor, mentee, day){ + for (i = 0; i= mentee_time[1])){ + if ((mentor.gender == mentee.gender) && (mentor.language == mentee.language) && (mentor.transport == mentor.transport)){ + mentor.addMatch([mentee.name, day, mentee.time, mentee.school]); + } + } + } +} + +// RETURNS ELIGIBLE MENTORS AND MENTEES MATCHINGS +function eligible(){ + var list_of_days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]; + var Mentor_Keys = Object.keys(Mentors); + var Mentee_Keys = Object.keys(Mentees); + for (var n = 0; n= 0)) { + temp_list.push(current_info[0]); + } + } + prematching_dict[current_mentor_name] = temp_list; + } + return prematching_dict; +} + +function remove_matched_mentees(input_list){ + var mentor_keys = Object.keys(Mentors); + for (i=0; i -1) { + matches.splice(index, 1); + current_mentor.matches = matches; + y = 0; + } + } + else{y+=1}; + } + } + } +} + +function returning_matches() { + + var returning_matches = {}; + var returner = data_mentor[0].indexOf("Were you a mentor last year?"); + var menteeNamecol = data_mentor[0].indexOf("If you would prefer to be paired with the same mentee, what was your mentee's name? (First and Last name)"); + var checkMenteeNames = data_mentee[0].indexOf("Name of Student (First, Last)"); + var mentees_to_remove = []; + //Creating a list with all mentees + for (var i = 1; i < data_mentor.length; i++){ + if (data_mentor[i][returner] == "Yes"){ + var mentorName = data_mentor[i][mentor_name_col] + var pastMentee = data_mentor[i][menteeNamecol]; + for (var j = 1; j < data_mentee.length; j++){ + if (data_mentee[j][mentee_name_col] == pastMentee){ + returning_matches[mentorName] = pastMentee; + } + } + } + } + + var returning_keys = Object.keys(returning_matches); + for (i = 0; i < returning_keys.length; i++){ + var current_mentor_name = returning_keys[i]; + var current_mentor_object = Mentors[current_mentor_name]; + var matches = current_mentor_object.matches; + for (j = 0; j < matches.length; j++){ + var current_info = matches[j]; + if (current_info[0] == returning_matches[current_mentor_name]){ + if (!(mentees_to_remove.indexOf(current_info[0]) >= 0)){ + mentees_to_remove.push(returning_matches[current_mentor_name]);} + delete Mentors[current_mentor_name]; + } + } + } + return mentees_to_remove; + +} + +// NOTES +//need to maybe fix some areas where there are multiple available times for a mentor in a day that aren't concatenated +//also need to decide what to do with mentors who are not elligible with any mentees besides remove them + +/** +function main(){ + check_preferences(); + eligible(); + remove_uneligible(); + remove_matched_mentees(returning_matches()); + Logger.log(output_for_matching()); +} +**/ +