eflips-eval 1.2.1__tar.gz → 1.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eflips-eval
3
- Version: 1.2.1
3
+ Version: 1.2.2
4
4
  Summary:
5
5
  Author: Ludger Heide
6
6
  Author-email: ludger.heide@lhtechnologies.de
@@ -1,26 +1,10 @@
1
+ from collections import Counter
1
2
  from datetime import datetime
2
3
  from typing import Dict, List
3
4
 
4
5
  import pandas as pd
5
6
  import sqlalchemy
6
- from eflips.model import Rotation, Trip
7
-
8
-
9
- def rotation_name_for_sorting(rotation_name: str) -> str:
10
- """
11
- Takes a rotation name, which in the BVG is a string of two numbers separated by a '/' character, and returns a string
12
- that can be used for sorting. The first part of the string is returned for BVG rotations.
13
-
14
- Other rotation names are not supported and will return the rotation name itself.
15
-
16
- :param rotation_name: The rotation name
17
- :return: a sortable string
18
- """
19
-
20
- if rotation_name is not None and "/" in rotation_name:
21
- return rotation_name.split("/")[0]
22
- else:
23
- return rotation_name
7
+ from eflips.model import Rotation, Trip, Route
24
8
 
25
9
 
26
10
  def rotation_info(
@@ -40,6 +24,9 @@ def rotation_info(
40
24
  - time_start: the departure of the first trip
41
25
  - time_end: the arrival of the last trip
42
26
  - line_name: the name of the line, which is the first part of the rotation name. Used for sorting
27
+ - line_is_unified: True if the rotation only contains one line
28
+ - start_station: the name of the departure station
29
+ - end_station: the name of the arrival station
43
30
 
44
31
  :param scenario_id: The scenario id for which to create the dataframe
45
32
  :param session: An sqlalchemy session to an eflips-model database
@@ -49,7 +36,22 @@ def rotation_info(
49
36
 
50
37
  result: List[Dict[str, int | float | str | datetime]] = []
51
38
 
52
- rotations = session.query(Rotation).filter(Rotation.scenario_id == scenario_id)
39
+ rotations = (
40
+ session.query(Rotation)
41
+ .filter(Rotation.scenario_id == scenario_id)
42
+ .options(
43
+ sqlalchemy.orm.joinedload(Rotation.trips)
44
+ .joinedload(Trip.route)
45
+ .joinedload(Route.line),
46
+ sqlalchemy.orm.joinedload(Rotation.vehicle_type),
47
+ sqlalchemy.orm.joinedload(Rotation.trips)
48
+ .joinedload(Trip.route)
49
+ .joinedload(Route.departure_station),
50
+ sqlalchemy.orm.joinedload(Rotation.trips)
51
+ .joinedload(Trip.route)
52
+ .joinedload(Route.arrival_station),
53
+ )
54
+ )
53
55
 
54
56
  if rotation_ids is not None:
55
57
  if isinstance(rotation_ids, int):
@@ -62,6 +64,16 @@ def rotation_info(
62
64
  for trip in rotation.trips:
63
65
  distance += trip.route.distance / 1000
64
66
 
67
+ # We want to be able to sort and/or group by line. Therefore we need to identify the predominant line name for each
68
+ # rotation.
69
+ line_names: Dict[str, int] = {}
70
+ for trip in rotation.trips:
71
+ line_name = trip.route.line.name
72
+ if line_name not in line_names:
73
+ line_names[line_name] = 0
74
+ line_names[line_name] += 1
75
+ line_name = Counter(line_names).most_common(1)[0][0]
76
+
65
77
  result.append(
66
78
  {
67
79
  "rotation_id": rotation.id,
@@ -69,16 +81,17 @@ def rotation_info(
69
81
  "vehicle_type_id": rotation.vehicle_type_id,
70
82
  "vehicle_type_name": rotation.vehicle_type.name,
71
83
  "total_distance": distance,
84
+ "line_name": line_name,
85
+ "line_is_unified": len(line_names)
86
+ == 1, # True if there is only one line in the rotation
72
87
  "time_start": rotation.trips[0].departure_time,
73
88
  "time_end": rotation.trips[-1].arrival_time,
89
+ "start_station": rotation.trips[0].route.departure_station.name,
90
+ "end_station": rotation.trips[-1].route.arrival_station.name,
74
91
  }
75
92
  )
76
93
 
77
- # We want to properly sort by rotation name, which is a bit intricate, as it's a string of two numbers divided by a
78
- # '/' character. We can't just sort by the string, as "10/11" would come after "10/1". We need to split the string
79
- # into its components and sort by them.
80
94
  df = pd.DataFrame(result)
81
- df["line_name"] = df["rotation_name"].apply(rotation_name_for_sorting)
82
95
 
83
96
  df.sort_values(by=["line_name", "time_start"], inplace=True)
84
97
 
@@ -19,6 +19,9 @@ def rotation_info(prepared_data: pd.DataFrame) -> go.Figure:
19
19
  - time_start: the departure of the first trip
20
20
  - time_end: the arrival of the last trip
21
21
  - line_name: the name of the line, which is the first part of the rotation name. Used for sorting
22
+ - line_is_unified: True if the rotation only contains one line
23
+ - start_station: the name of the departure station
24
+ - end_station: the name of the arrival station
22
25
 
23
26
  :return: A plotly figure object
24
27
  """
@@ -30,11 +33,22 @@ def rotation_info(prepared_data: pd.DataFrame) -> go.Figure:
30
33
  y="rotation_name",
31
34
  color="total_distance",
32
35
  labels={
36
+ "time_start": "Departure Time",
37
+ "time_end": "Arrival Time",
33
38
  "rotation_name": "Rotation Name",
34
39
  "total_distance": "Total Distance (km)",
35
40
  "line_name": "Line Name",
41
+ "vehicle_type_name": "Vehicle Type Name",
42
+ "start_station": "Start Station",
43
+ "end_station": "End Station",
36
44
  },
37
- hover_data=["vehicle_type_name"],
45
+ hover_name="rotation_name",
46
+ hover_data=[
47
+ "vehicle_type_name",
48
+ "total_distance",
49
+ "start_station",
50
+ "end_station",
51
+ ],
38
52
  pattern_shape="line_name",
39
53
  )
40
54
  fig.update_layout(legend_orientation="h")
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "eflips-eval"
3
- version = "1.2.1"
3
+ version = "1.2.2"
4
4
  description = ""
5
5
  authors = [
6
6
  "Ludger Heide <ludger.heide@lhtechnologies.de>",
File without changes
File without changes