def busReschedule_run(schedule_filename, accesskey, secretkey, broken_run, path_to_outdir = af.os.path.join(af.os.getcwd(),'data'), resched_init_time = None, bookingid = None, windows = 1800., radius = 3.): ''' schedule_filename (str): name of file to be used if you want to test a DEMO file. Must be a single day, QC'ed file. accesskey (str): AWS_ACCESS_KEY secretkey (str): AWS_SECRET_KEY bookingid (?): list of BookingIds to be rescheduled (comma separated?) broken_run (str): name of broken run. windows (float): size of time windows, in seconds resched_init_time (int): seconds in day at which rescheduling can occur. path_to_outdir (str): path to directory where you would like to store all output files. radius (float): number of miles to search for close buses. Will be shrunk by increments of 1 if number of nearby buses is > 30. ''' flag = 200 #400's are bad, 200 is good. if not af.os.path.exists(path_to_outdir): path_to_outdir = af.os.path.join(af.os.getcwd(),'data') #get rescheduling data from the webapp/data directory if schedule_filename is not None: if af.os.path.isfile(af.os.path.join(path_to_outdir, schedule_filename)): fullSchedule = af.pd.DataFrame.from_csv(schedule_filename, header=0, sep=',', index_col = False) else: print('ERROR 401: Demo file not found!') flag = 401 return flag if accesskey and secretkey is not None: #AWS_ACCESS_KEY = raw_input("Please enter AWS access key: ") #AWS_SECRET_KEY = raw_input("Please enter AWS secret key: ") try: fullSchedule = af.s3_data_acquire(accesskey, secretkey, path_to_outdir, qc_file_name = 'qc_streaming.csv') if type(fullSchedule) == int: print("ERROR 402: formatting error in streaming data.") flag = 402 return flag except IOError: #is this the right error if s3_data_acquire fails? print('ERROR 403: Could not access streaming data!') flag = 403 return flag #Determine broken run number, or get list of unhandled requests. if broken_run is not None: case = 'BROKEN_RUN' elif bookingid is not None: case = 'INDIVIDUAL_REQUESTS' individual_requests = list(bookingid) # this simply returns full schedule with time windows at the moment sched_obj = af.aTWC.TimeWindowsCapacity(fullSchedule) fullSchedule_windows = sched_obj.addtoRun_TimeCapacity(windows) fS_w_copy = fullSchedule_windows.copy() #this gets us all the URIDs for the broken run given the initial rescheduling time #OR it will get us URIDs given specific bookingIds to be rescheduled if case == 'BROKEN_RUN': if broken_run not in list(set(fullSchedule_windows.Run.tolist())): print('ERROR 404: Run number is not scheduled for today!') flag = 404 return flag if resched_init_time is not None: resched_init_time = af.humanToSeconds(resched_init_time) if resched_init_time is None: t = af.datetime.datetime.now() hr = str(t.hour) if t.minute < 10: m = str(0)+str(t.minute) else: m = str(t.minute) t = hr+':'+m resched_init_time = af.humanToSeconds(t) URIDs = af.get_URID_Bus(fullSchedule_windows, broken_run, resched_init_time) else: for i in range(len(individual_requests)): if individual_requests[i] not in list(set(fullSchedule_windows.BookingId.tolist())): print('ERROR 405: You have entered BookingIds not present in the schedule!') flag = 405 return flag URIDs = af.get_URID_BookingIds(fullSchedule_windows, individual_requests) if not URIDs: print('ERROR 406: There are no people to reschedule on bus {0} at time {1}'.format(broken_run, resched_init_time)) flag = 406 return flag # for each URID we find the bus runs to check through a radius elimination. # for each URID for each run we then want to check the capacity in the given time # window and return the URID with updated insert points. This URID with updated # insert points is fed to the feasibilty function, which we ultimately want to return # a minimum cost run for the URID and that run updated with the new URID slotted in. taxi_costs = [] delay_costs = [] best_buses = [] for i in range(len(URIDs)): print('Rescheduling URID {0}'.format(i)) busRuns_tocheck = af.radius_Elimination(fullSchedule_windows, URIDs[i], radius=radius) insert_stats = [] #iterate over all runs, find best one! for run in busRuns_tocheck: this_run = fullSchedule_windows[fullSchedule_windows['Run']==run] capacity_obj = af.checkCap.CapacityInsertPts(this_run) #Kristen's capacity checker: URIDs[i].PickupInsert, URIDs[i].DropoffInsert = capacity_obj.return_inserts(URIDs[i]) # IF THERE'S ROOM: TEST FEASIBILITY if not af.np.isnan(URIDs[i].PickupInsert): URIDs[i].PickupStart = URIDs[i].PickupInsert URIDs[i].DropoffStart = URIDs[i].DropoffInsert runSchedule = af.get_busRuns(fullSchedule_windows, run, None) print('Testing feasibility for run ' + run) brokenwindows_dict =af.insertFeasibility(runSchedule, URIDs[i]) if not brokenwindows_dict: print('Run {0} infeasible without moving the return-to-garage row.'.format(run)) else: insert_stats.append(brokenwindows_dict) #ASSEMBLE and ORDER transit options. if insert_stats: #ORDER buses by lowest additional lag time, i.e. total_lag, and sequentially add total_lag's ordered_inserts = sorted(insert_stats, key = af.operator.itemgetter('additional_time')) popme = [] for k in range(len(ordered_inserts)): if ordered_inserts[k]['RunID']==broken_run: popme.append(k) if popme: ordered_inserts.pop(popme) delay_costs.append(ordered_inserts[0]['additional_time'][0]*(48.09/3600)) #total dollars best_buses.append(ordered_inserts[0]['RunID']) #CALCULATE taxi cost taxi_costs.append(af.taxi(URIDs[i])) #WRITE information about best insertions to text file if len(ordered_inserts) >= 3: af.write_insert_data(URIDs[i], ordered_inserts[0:3], path_to_outdir, taxi_costs[i]) else: af.write_insert_data(URIDs[i], ordered_inserts[0:], path_to_outdir, taxi_costs[i]) #UPDATE whole day's schedule: fullSchedule_windows = af.day_schedule_Update(data = fullSchedule_windows, top_Feasibility = ordered_inserts[0], URID = URIDs[i]) sched_obj_update = af.aTWC.TimeWindowsCapacity(fullSchedule_windows) fullSchedule_windows = sched_obj_update.add_Capacity(update = True) #SAVE just the updated run for each URID fullSchedule_windows[fullSchedule_windows['Run'] == ordered_inserts[0]['RunID']].to_csv(af.os.path.join(path_to_outdir, str(str(int(URIDs[i].BookingId))+'_schedule.csv')), index = False) else: delay_costs.append(400000) taxi_costs.append(af.taxi(URIDs[i])) af.write_insert_data(URIDs[i], None, path_to_outdir, taxi_costs[i]) best_buses.append('NA') #WRITE csv of PREFERRED OPTIONS: if case == 'BROKEN_RUN': nrun_cost = af.newBusRun_cost(af.get_busRuns(fS_w_copy, broken_run, URIDs[0]), provider = 6) else: nrun_cost = None pref_opt = af.preferred_options(URIDs, best_buses, delay_costs, taxi_costs, nrun_cost) pref_opt.to_csv(af.os.path.join(path_to_outdir, 'preferred_options.csv'), index = False) return flag
ordered_inserts = sorted( insert_stats, key=af.operator.itemgetter('additional_time')) popme = [] for k in range(len(ordered_inserts)): if ordered_inserts[k]['RunID'] == broken_run: popme.append(k) if popme: ordered_inserts.pop(popme) delay_costs.append(ordered_inserts[0]['additional_time'][0] * (48.09 / 3600)) #total dollars best_buses.append(ordered_inserts[0]['RunID']) #CALCULATE taxi cost taxi_costs.append(af.taxi(URIDs[i])) #WRITE information about best insertions to text file if len(ordered_inserts) >= 3: af.write_insert_data(URIDs[i], ordered_inserts[0:3], path_to_outdir, taxi_costs[i]) else: af.write_insert_data(URIDs[i], ordered_inserts[0:], path_to_outdir, taxi_costs[i]) #UPDATE whole day's schedule: fullSchedule_windows = af.day_schedule_Update( data=fullSchedule_windows, top_Feasibility=ordered_inserts[0], URID=URIDs[i]) sched_obj_update = af.aTWC.TimeWindowsCapacity(
delay_cost = 0 for i in range(len(URIDs)): busRuns_tocheck = af.radius_Elimination(fullSchedule_windows, URIDs[i], radius=5.) insert_stats = [] for run in busRuns_tocheck: URID_updated_insertpts = checkCapacityInsertPts(URIDs[i],run) runSchedule = af.get_busRuns(fullSchedule_windows, run, None) brokenwindows_dict =af.insertFeasibility(runSchedule, URID_updated_insertpts) insert_stats.append(brokenwindows_dict) #order buses by lowest additional lag time, i.e. total_lag, and sequentially add total_lag's ordered_inserts = sorted(insert_stats, key = af.operator.itemgetter('total_lag')) delay_cost += ordered_inserts[0]['total_lag'][0]*(48.09/3600) #total dollars #calculate taxi cost taxi_cost = af.taxi(URIDs[i].PickUpCoords.LAT, URIDs[i].PickUpCoords.LON, URIDs[i].DropOffCoords.LAT, DropOffCoords.LON, af.wheelchair_present(URIDs[i])) #write information about best insertions to text file af.write_insert_data(URID, ordered_inserts[0:3], '/Users/fineiskid/Desktop/DSSG_ffineis/main_repo/Access_Analysis_Rproject/data/output/', taxi_cost) #update whole day's schedule: fullSchedule_windows = af.day_schedule_Update(fullSchedule_windows, ordered_inserts[0], URIDs[i]) #Calculate new bus's cost, ONLY IN CASE OF BROKEN BUS: if case == 'BROKEN_RUN': newRun_cost = af.newBusRun_cost(af.get_busRuns(fS_w_copy, broken_Run, URIDs[0]), provider) # for provider we need to check availability of buses and compare costs---^^^ print('Cost of sending new bus for broken run {0} is {1}.'.format(broken_Run, newBusRun_cost)) print('Cost of rerouting all URIDs is {0}'.format(delay_cost))