def apply_entry_then_clause(self, then_clauses, entry_location, entry_time, train_locations, potential_entry): # TODO refactor this method and apply_locations_then_clause to use common code. for clause in then_clauses: if 'entry_point' in clause: potential_entry = clause['entry_point'] if 'entry_time' in clause: if re.match('\\d{4}', clause['entry_time']) is not None: entry_time = clause['entry_time'] else: entry_time = self.determine_entry_time_from_location( clause['entry_time'], train_locations, entry_time) if 'remove_1st_of' in clause: for l_to_remove in clause['remove_1st_of']: train_locations = self.remove_nth_location( common.find_readable_location(l_to_remove, self.locations_map), 1, train_locations) if 'remove_all_of' in clause: for l_to_remove in clause['remove_all_of']: train_locations = self.remove_all_of_location( common.find_readable_location(l_to_remove, self.locations_map), train_locations) if 'modify_location' in clause: train_locations = self.modify_location( clause['modify_location'], train_locations) if 'remove_props_from_location' in clause: train_locations = self.remove_props_from_location( clause['remove_props_from_location'], train_locations) return [ potential_entry, entry_time, 'templates/timetables/defaultTimetable.txt', train_locations ]
def modify_location(self, location_modifications, train_locations): location_modifications_copy = location_modifications.copy() if 'location' in location_modifications_copy: readable_l = common.find_readable_location( location_modifications_copy.pop('location'), self.locations_map) for l in train_locations: if l['location'] == readable_l: for prop in location_modifications_copy: l[prop] = location_modifications[prop] elif 'new_location' in location_modifications_copy: new_readable_l = common.find_readable_location( location_modifications_copy.pop('new_location'), self.locations_map) old_readable_l = common.find_readable_location( location_modifications_copy.pop('old_location'), self.locations_map) for l in train_locations: if l['location'] == old_readable_l: l['location'] = new_readable_l for prop in location_modifications_copy: l[prop] = location_modifications[prop] return train_locations
def is_location_at_index(self, location_name, index, train_locations): if index > len(train_locations) - 1: return False return train_locations[index][ 'location'] == common.find_readable_location( location_name, self.locations_map)
def remove_props_from_location(self, location_with_props, train_locations): readable_l = common.find_readable_location( location_with_props['location'], self.locations_map) for l in train_locations: if l['location'] == readable_l: for prop in location_with_props['props']: l.pop(prop) return train_locations
def determine_entry_time_from_location(self, location_name, train_locations, entry_time): readable_l_name = common.find_readable_location( location_name, self.locations_map) if readable_l_name == '': return entry_time for l in train_locations: if l['location'] == readable_l_name: if 'dep' in l: return l['dep'] if 'arr' in l: return l['arr'] return entry_time
def apply_locations_then_clause(self, then_clauses, train_locations): for clause in then_clauses: if 'remove_1st_of' in clause: for l_to_remove in clause['remove_1st_of']: train_locations = self.remove_nth_location( common.find_readable_location(l_to_remove, self.locations_map), 1, train_locations) if 'remove_all_of' in clause: for l_to_remove in clause['remove_all_of']: train_locations = self.remove_all_of_location( common.find_readable_location(l_to_remove, self.locations_map), train_locations) if 'modify_location' in clause: train_locations = self.modify_location( clause['modify_location'], train_locations) if 'remove_props_from_location' in clause: train_locations = self.remove_props_from_location( clause['remove_props_from_location'], train_locations) return train_locations
def are_x_y_concurrent(self, location1, location2, train_locations): """ Returns index of location 1 if condition satisfied, o.w. will return -1 """ readable_l1 = common.find_readable_location(location1, self.locations_map) readable_l2 = common.find_readable_location(location2, self.locations_map) if any(readable_l1 == l['location'] for l in train_locations) is False or any( readable_l2 == l['location'] for l in train_locations) is False: return -1 for i in range(len(train_locations) - 1): if train_locations[i][ 'location'] == readable_l1 and train_locations[ i + 1]['location'] == readable_l2: return i return -1
def remove_nth_location(self, location_to_remove, nth_time, train_locations): standard_location_to_remove = common.find_readable_location( location_to_remove, self.locations_map) count_times_seen = 0 new_locations = train_locations.copy() for i in range(len(train_locations)): if train_locations[i]['location'] == standard_location_to_remove: count_times_seen += 1 if count_times_seen == nth_time: new_locations.pop(i) return new_locations return new_locations
def x_before_y(self, x, y, train_locations): """ Will return none if cant find either in locations. Will return false if same location. """ x_readable = common.find_readable_location(x, self.locations_map) y_readable = common.find_readable_location(y, self.locations_map) x_pos = -1 y_pos = -1 for i in range(len(train_locations)): if train_locations[i]['location'] == x_readable: x_pos = i if train_locations[i]['location'] == y_readable: y_pos = i if x_pos == -1 or y_pos == -1: print('One of values not in locations') return None return x_pos < y_pos
def is_condition_met(self, condition, entry_point, train_locations): if 'entry_point' in condition: c_entry = condition['entry_point'] if c_entry[0] == '!': return c_entry[1:] != entry_point return c_entry == entry_point if 'location' in condition: condition['location'] = common.find_readable_location( condition['location'], self.locations_map) for location in train_locations: if all( self.is_property_in_condition_satisfied( prop, condition[prop], location) for prop in condition) is True: return True return False
def get_entry_location_in_train_locs(self, potential_entry, train_locations): """ Returns an associated entry location name if found. """ if potential_entry is not None: tiploc_for_entry = self.entry_points_map[potential_entry][ 'assoc_sim_location'] readable_entry_name = common.find_readable_location( tiploc_for_entry, self.locations_map) entry_location = self.get_entry_location_in_list( readable_entry_name, train_locations) if entry_location is not None: return entry_location['location'] return None
def x_after_time(self, x, time, train_locations): """ Will return false if cant find x in locations. Will return false if same time. """ x_readable = common.find_readable_location(x, self.locations_map) x_time = None for l in train_locations: if l['location'] == x_readable: if 'dep' in l: x_time = l['dep'] elif 'arr' in l: x_time = l['arr'] if x_time is None: return False time_as_num = float(time) return time_as_num < float(x_time)
def convert_train_locations(initial_locations: list, location_maps: list, source_location: str) -> list: """ :param initial_locations: the list of locations scraped from source. :param location_maps: the entry and sim location maps :param source_location: used if we have times spanning more than one day. :return: [ readable list of locations on sim, the potential entry point for the train ] """ # get the map of sim locations [entry_points, locations_map] = location_maps # create list of entry point names list_of_entry_points = [] for entry_point in entry_points: for elt in entry_points[entry_point]['readable_names']: list_of_entry_points.append(elt) if entry_points[entry_point]['assoc_sim_location'] is not None: list_of_entry_points.append( entry_points[entry_point]['assoc_sim_location']) # for each location check if potential entry point then check if in locations (both sides) potential_entry_point = None potential_entry_time = None new_locations = [] for location in initial_locations: if 'Activities' in location: if 'Stops to change trainmen' in location['Activities']: location['activities'] = [["crewChange", None]] if location[ 'Location'] in list_of_entry_points and potential_entry_point is None: for entry_point in entry_points.keys(): if location['Location'] in entry_points[entry_point]['readable_names'] or \ (entry_points[entry_point]['assoc_sim_location'] is not None and location['Location'] in entry_points[entry_point]['assoc_sim_location']): potential_entry_point = entry_point if 'dep' in location: potential_entry_time = location['dep'] elif 'arr' in location: potential_entry_time = location['arr'] # check l keys loc = common.find_readable_location(location['Location'], locations_map) if loc != '': location['location'] = loc new_locations.append(location) location.pop('Location') continue # check l values loc = common.find_tiploc_for_location(location['Location'], locations_map) if loc != '': location['location'] = locations_map[loc] location.pop('Location') new_locations.append(location) continue if times_span_multiple_days(new_locations) is True: readable_source_location = common.find_readable_location( source_location, locations_map) location_on_day = list( filter(lambda x: x['location'] == readable_source_location, new_locations))[0] if do_times_cross_midnight(new_locations[0], location_on_day): new_locations = remove_locations_before_0000(new_locations) elif do_times_cross_midnight(location_on_day, new_locations[-1]): new_locations = add_time_to_locations_after_0000(new_locations) return [new_locations, potential_entry_point, potential_entry_time]
def remove_all_of_location(self, location_to_remove, train_locations): standard_location_to_remove = common.find_readable_location( location_to_remove, self.locations_map) return list( filter(lambda x: x['location'] != standard_location_to_remove, train_locations))