def choose_stop(rs: List[RouteSection]) -> Maybe[m.Stop]: if len(rs) == 0: return Nothing() elif len(rs) == 1: return Just(rs[0].s1) elif rs[0].s2 == rs[1].s1: return Just(rs[0].s2) else: return Just(rs[0].s1)
def section_times( snapshots: List[Tuple[db.BusSnapshot, Dict[api.TimetableVariant, Set[int]]]], sections: Dict[api.TimetableVariant, List[RouteSection]], ) -> Dict[api.TimetableVariant, List[SectionTime]]: """Calculates entry and exit times for each section in snapshots. Arguments: snapshots: The bus snapshots, each with, for each timetable variant, the sections that snapshot falls in. sections: The sections in each timetable variant (in order). Returns: For each timetable variant, the route sections that were entered and exited in snapshots, in order of exit. """ section_windows: Dict[api.TimetableVariant, List[SectionTime]] = defaultdict(list) sections_entered: Dict[Tuple[api.TimetableVariant, int], EntryWindow] = {} last_positions: Dict[api.TimetableVariant, Set[int]] = {} last_time: Maybe[datetime] = Nothing() for snapshot, positions in snapshots: update_positions = False for variant, these_positions in positions.items(): if not these_positions: continue else: update_positions = True for position in these_positions.difference( last_positions.get(variant, set())): window = (last_time, Just(snapshot.poll_time)) sections_entered[(variant, position)] = window for position in last_positions.get( variant, set()).difference(these_positions): exit_interval = last_time, Just(snapshot.poll_time) section_time = SectionTime( (position, sections_entered[(variant, position)], exit_interval)) section_windows[variant].append(section_time) for variant, old_positions in last_positions.items(): if variant not in positions: for position in list(old_positions): exit_interval = last_time, Just(snapshot.poll_time) section_time = SectionTime( (position, sections_entered[(variant, position)], exit_interval)) section_windows[variant].append(section_time) old_positions.remove(position) if update_positions: last_positions = positions last_time = Just(snapshot.poll_time) return section_windows
def estimate(arrival: StopArrival) -> Maybe[Tuple[datetime, datetime]]: if isinstance(arrival, SeenAtStop): return Just((arrival.first_at, arrival.last_at)) elif isinstance(arrival, NotSeenAtStop): return arrival.last_before.bind( lambda before: arrival.first_after.map(lambda after: before + ( (after - before) / 2)).map(lambda a: (a, a)))
def route_sections( stops: Iterable[m.Stop], rectangle_width: float = 0.001, circle_radius: float = 0.001, ) -> Iterator[RouteSection]: def shapes() -> Iterator[RouteSection]: for s1, s2 in pairwise(stops): yield make_circle(s1, circle_radius) yield make_rectangle(s1, s2, rectangle_width) yield make_circle(s2, circle_radius) for section1, section2, section3 in drop( 1, (tuplewise_padded(3, (Just(x) for x in shapes()), pad_value=Nothing()))): if isinstance(section2, Just): if isinstance(section2.value, RoadSection): if isinstance(section1, Just) and isinstance( section1.value, StopCircle): section2 = section2.value.difference(section1.value) if isinstance(section3, Just) and isinstance( section3.value, StopCircle): section2 = section2.bind( lambda s: s.difference(section3.value)) if isinstance(section2, Just): yield section2.value
def timetable( timetable_id: int, connection: Maybe[connection] = Nothing() ) -> Either[str, Timetable]: with connection.or_else_lazy(default_connection) as conn: with conn.cursor() as cursor: cursor.execute( """ select caption from timetables where id = %s """, [timetable_id], ) result = cursor.fetchone() if result is None: return Left(f"Timetable {timetable_id} not in database") caption = result[0] cursor.execute( """ select id from timetable_variants where timetable_id = %s """, [timetable_id], ) variants = (timetable_variant(id, Just(conn)) for (id, ) in cursor.fetchall()) return Right( Timetable(caption, {v.value for v in variants if isinstance(v, Right)}))
def cell_time(t: Tag) -> Maybe[time]: contents = "".join([s for s in t.stripped_strings]) if contents.endswith("[+1]"): contents = contents[:-4] try: return Just(time.fromisoformat(contents)) except ValueError: return Nothing()
def match_stop_name(stops: Dict[str, Stop], name: str) -> Maybe[Stop]: name = name.strip() if name == "Cork Railway Station (Kent)": name = "Kent Rail Station (Horgans Quay)" prefixes: Iterable[str] = chain([name], takewhile(lambda s: s != "", iterate(lambda s: s[:-1], name))) for p in prefixes: if p in stops: return Just(stops[p]) return Nothing()
def timetables( route: RouteId, connection: Maybe[connection] = Nothing() ) -> Iterator[Either[str, Timetable]]: """Gets the timetables for a specific route from the database.""" with connection.or_else_lazy(default_connection) as conn: with conn.cursor() as cursor: cursor.execute( """ select timetable from route_timetables where route = %s """, [route.raw], ) for (timetable_id, ) in cursor.fetchall(): yield timetable(timetable_id, Just(conn))
def difference(self, circle: StopCircle) -> Maybe[RoadSection]: new_polygon = self.polygon.difference(circle.polygon) if isinstance(new_polygon, sg.Polygon): return Just(RoadSection(monkey_patch_polygon(new_polygon))) else: return Nothing()
def from_my_json(j: MyPassageJson) -> Passage: return Passage( id=Just(PassageId(cast(str, j["id"]))), last_modified=Just( datetime.fromisoformat(cast(str, j["last_modified"]))), trip=Just(TripId(cast(str, j["trip_id"]))), route=Just(RouteId(cast(str, j["route_id"]))), vehicle=Just(VehicleId(cast(str, j["vehicle_id"]))), stop=Just(StopId(cast(str, j["stop_id"]))), pattern=Just(PatternId(cast(str, j["pattern_id"]))), latitude=Just(cast(int, j["latitude"])), longitude=Just(cast(int, j["longitude"])), bearing=Just(cast(int, j["bearing"])), time=PassageTime.from_json(cast(MyPassageTimeJson, j["time"])), is_deleted=Just(cast(bool, j["is_deleted"])), is_accessible=Just(cast(bool, j["is_accessible"])), has_bike_rack=Just(cast(bool, j["has_bike_rack"])), direction=Just(cast(int, j["direction"])), congestion=Just(cast(int, j["congestion"])), accuracy=Just(cast(int, j["accuracy"])), status=Just(cast(int, j["status"])), category=Just(cast(int, j["category"])), )