Skip to content

Commit

Permalink
Extended the CFR JSON library.
Browse files Browse the repository at this point in the history
Changes made:
- added definitions for shipment type incompatibilities,
- added definitions for metrics,
- added a function that gets the break duration from a transition in a
  solution.
  • Loading branch information
ondrasej committed Dec 4, 2023
1 parent d30a374 commit 4a229e1
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
42 changes: 41 additions & 1 deletion python/cfr/json/cfr_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ class TransitionAttributes(TypedDict, total=False):
delay: DurationString


class ShipmentTypeIncompatibility(TypedDict, total=False):
"""Represents a shipment type incompatibility in the JSON CFR request."""

types: list[str]
incompatibilityMode: int


class ShipmentModel(TypedDict, total=False):
"""Represents a shipment model in the JSON CFR request."""

Expand All @@ -176,6 +183,8 @@ class ShipmentModel(TypedDict, total=False):
globalStartTime: TimeString
globalEndTime: TimeString

shipmentTypeIncompatibilities: list[ShipmentTypeIncompatibility]


class Visit(TypedDict, total=False):
"""Represents a single visit on a route in the JSON CFR results."""
Expand Down Expand Up @@ -289,12 +298,25 @@ class OptimizeToursRequest(TypedDict, total=False):
timeout: DurationString


class Metrics(TypedDict, total=False):
"""Represents the metrics in the JSON CFR response."""

aggregatedRouteMetrics: AggregatedMetrics
skippedMandatoryShipmentCount: int
usedVehicleCount: int
earliestVehicleStartTime: TimeString
latestVehicleEndTime: TimeString
costs: dict[str, float]
totalCost: float


class OptimizeToursResponse(TypedDict, total=False):
"""Represents the JSON CFR result."""

routes: list[ShipmentRoute]
skippedShipments: list[SkippedShipment]
totalCost: float
metrics: Metrics


# pylint: enable=invalid-name
Expand Down Expand Up @@ -447,6 +469,22 @@ def get_break_min_duration(break_request: BreakRequest) -> datetime.timedelta:
return parse_duration_string(break_request["minDuration"])


def get_transition_break_duration(transition: Transition) -> datetime.timedelta:
"""Returns the break time of a transition.
Args:
transition: The transition for which the break duration is computed.
Returns:
When there is a break over the given transition, returns its duration. When
there is no break, returns zero duration.
"""
duration_string = transition.get("breakDuration")
if duration_string is None:
return datetime.timedelta()
return parse_duration_string(duration_string)


def get_visit_request(model: ShipmentModel, visit: Visit) -> VisitRequest:
"""Returns the visit request used in `visit`."""
shipment_index = visit.get("shipmentIndex", 0)
Expand Down Expand Up @@ -942,7 +980,9 @@ def recompute_route_metrics(
end_time = parse_time_string(route["vehicleEndTime"])
if route_total_duration != end_time - start_time:
raise ValueError(
"The total duration is inconsistent with vehicle start and end times"
"The total duration is inconsistent with vehicle start and end"
f" times. Start time: {start_time}, end time: {end_time}, total"
f" duration: {route_total_duration}"
)

route["metrics"] = {
Expand Down
22 changes: 22 additions & 0 deletions python/cfr/json/cfr_json_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,28 @@ def test_get_min_duration(self):
)


class GetTransitionPropertiesTest(unittest.TestCase):
"""Tests for accessor functions for Transition."""

def test_get_break_duration_no_break(self):
self.assertEqual(
cfr_json.get_transition_break_duration(
{"travelDuration": "32s", "totalDuration": "32s"}
),
datetime.timedelta(),
)

def test_get_break_duration_with_break(self):
self.assertEqual(
cfr_json.get_transition_break_duration({
"travelDuration": "16s",
"breakDuration": "3600s",
"totalDuration": "3616s",
}),
datetime.timedelta(hours=1),
)


class GetUnavoidableBreaksTest(unittest.TestCase):
"""Tests for get_unavoidable_breaks."""

Expand Down

0 comments on commit 4a229e1

Please sign in to comment.