-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5bc56e8
commit 8e576a2
Showing
3 changed files
with
159 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
"""Defines the input class""" | ||
"""Defines the input class.""" | ||
|
||
from typing import Any | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
"""Defines the output class.""" | ||
|
||
from typing import Any | ||
|
||
from nextmv.base_model import BaseModel | ||
|
||
|
||
class Version(BaseModel): | ||
"""A version used for solving.""" | ||
|
||
sdk: str | ||
"""Nextmv SDK.""" | ||
|
||
|
||
class Solution(BaseModel): | ||
"""Solution to a Vehicle Routing Problem (VRP).""" | ||
|
||
|
||
class RunStatistics(BaseModel): | ||
"""Statistics about a general run.""" | ||
|
||
duration: float | None = None | ||
"""Duration of the run in seconds.""" | ||
iterations: int | None = None | ||
"""Number of iterations.""" | ||
custom: Any | None = None | ||
"""Custom statistics created by the user. Can normally expect a `dict[str, | ||
Any]`.""" | ||
|
||
|
||
class ResultStatistics(BaseModel): | ||
"""Statistics about a specific result.""" | ||
|
||
duration: float | None = None | ||
"""Duration of the run in seconds.""" | ||
value: float | None = None | ||
"""Value of the result.""" | ||
custom: Any | None = None | ||
"""Custom statistics created by the user. Can normally expect a `dict[str, | ||
Any]`.""" | ||
|
||
|
||
class DataPoint(BaseModel): | ||
"""A data point.""" | ||
|
||
x: float | ||
"""X coordinate of the data point.""" | ||
y: float | ||
"""Y coordinate of the data point.""" | ||
|
||
|
||
class Series(BaseModel): | ||
"""A series of data points.""" | ||
|
||
name: str | None = None | ||
"""Name of the series.""" | ||
data_points: list[DataPoint] | None = None | ||
"""Data of the series.""" | ||
|
||
|
||
class SeriesData(BaseModel): | ||
"""Data of a series.""" | ||
|
||
value: Series | None = None | ||
"""A series for the value of the solution.""" | ||
custom: list[Series] | None = None | ||
"""A list of series for custom statistics.""" | ||
|
||
|
||
class Statistics(BaseModel): | ||
"""Statistics of a solution.""" | ||
|
||
schema: str | ||
"""Schema (version).""" | ||
|
||
run: RunStatistics | None = None | ||
"""Statistics about the run.""" | ||
result: ResultStatistics | None = None | ||
"""Statistics about the last result.""" | ||
series_data: SeriesData | None = None | ||
"""Data of the series.""" | ||
|
||
|
||
class Output(BaseModel): | ||
"""Output schema for Nextroute.""" | ||
|
||
options: dict[str, Any] | ||
"""Options used to obtain this output.""" | ||
version: Version | ||
"""Versions used for the solution.""" | ||
|
||
solutions: list[Solution] | None = None | ||
"""Solutions to the problem.""" | ||
statistics: Statistics | None = None | ||
"""Statistics of the solution.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import json | ||
import math | ||
import unittest | ||
|
||
from nextmv.nextroute.schema.output import ResultStatistics | ||
|
||
|
||
class TestOutput(unittest.TestCase): | ||
def test_result_statistics_decoding(self): | ||
test_cases = [ | ||
{ | ||
"name": "value is float", | ||
"json_stats": '{"duration": 0.1, "value": 1.23}', | ||
}, | ||
{ | ||
"name": "value is nan", | ||
"json_stats": '{"duration": 0.1, "value": "nan"}', | ||
}, | ||
{ | ||
"name": "value is infinity", | ||
"json_stats": '{"duration": 0.1, "value": "inf"}', | ||
}, | ||
{ | ||
"name": "value is infinity 2", | ||
"json_stats": '{"duration": 0.1, "value": "+inf"}', | ||
}, | ||
{ | ||
"name": "value is -infinity", | ||
"json_stats": '{"duration": 0.1, "value": "-inf"}', | ||
}, | ||
] | ||
|
||
for test in test_cases: | ||
dict_stats = json.loads(test["json_stats"]) | ||
stats = ResultStatistics.from_dict(dict_stats) | ||
self.assertTrue(isinstance(stats, ResultStatistics)) | ||
self.assertTrue(isinstance(stats.value, float)) | ||
|
||
def test_result_statistics_encoding(self): | ||
test_cases = [ | ||
{ | ||
"name": "value is float", | ||
"stats": ResultStatistics(duration=0.1, value=1.23), | ||
}, | ||
{ | ||
"name": "value is nan", | ||
"stats": ResultStatistics(duration=0.1, value=math.nan), | ||
}, | ||
{ | ||
"name": "value is infinity", | ||
"stats": ResultStatistics(duration=0.1, value=math.inf), | ||
}, | ||
{ | ||
"name": "value is -infinity", | ||
"stats": ResultStatistics(duration=0.1, value=-1 * math.inf), | ||
}, | ||
] | ||
|
||
for test in test_cases: | ||
stats = test["stats"] | ||
dict_stats = stats.to_dict() | ||
self.assertTrue(isinstance(dict_stats, dict)) | ||
self.assertTrue(isinstance(dict_stats["value"], float)) |