feat: add time limit parsing function and update time_to_run parameter to accept string inputs

This commit is contained in:
Ross
2026-07-14 22:00:26 +01:00
parent 0874f05126
commit d577b2cdf8
3 changed files with 65 additions and 8 deletions
+26 -3
View File
@@ -507,11 +507,34 @@ def load_workers():
def parse_time_limit(t) -> int:
"""Parses a time limit string (e.g. '10h', '30m', '45s') or an integer to seconds."""
if isinstance(t, int):
return t
if isinstance(t, float):
return int(t)
t = str(t).strip().lower()
if not t:
return 0
if t.isdigit():
return int(t)
if t.endswith("h"):
return int(float(t[:-1]) * 3600)
if t.endswith("m"):
return int(float(t[:-1]) * 60)
if t.endswith("s"):
return int(float(t[:-1]))
try:
return int(float(t))
except ValueError:
raise ValueError(f"Invalid time format: {t}. Expected format like '10h', '30m', '45s' or a number of seconds.")
@app.command()
def main(
suspend: bool = False,
solve: bool = True,
time_to_run: int = 60 * 60,
time_to_run: str = "1h",
ratio: float = 0.1,
start_date: datetime.datetime = ROTA_START_DATE,
weeks: int = 22,
@@ -698,8 +721,8 @@ def main(
# Rota.build_workers()
# Rota.build_model()
solver_options = {"ratio": ratio, "seconds": time_to_run, "threads": 10}
# solver_options = {"seconds": time_to_run, "threads": 10}
seconds_to_run = parse_time_limit(time_to_run)
solver_options = {"ratio": ratio, "seconds": seconds_to_run, "threads": 10}
# start_time = time.time()
Rota.build_and_solve(solver_options, export=True, export_with_timestamp=False, solve=solve, solver="appsi_highs")
+26 -4
View File
@@ -46,12 +46,34 @@ from rota_generator.workers import (
OutOfProgramme,
)
# TODO update time_to_run to accept a string like "10h" or "30m" and convert to seconds
def parse_time_limit(t) -> int:
"""Parses a time limit string (e.g. '10h', '30m', '45s') or an integer to seconds."""
if isinstance(t, int):
return t
if isinstance(t, float):
return int(t)
t = str(t).strip().lower()
if not t:
return 0
if t.isdigit():
return int(t)
if t.endswith("h"):
return int(float(t[:-1]) * 3600)
if t.endswith("m"):
return int(float(t[:-1]) * 60)
if t.endswith("s"):
return int(float(t[:-1]))
try:
return int(float(t))
except ValueError:
raise ValueError(f"Invalid time format: {t}. Expected format like '10h', '30m', '45s' or a number of seconds.")
@app.command()
def main(
suspend: bool = False,
solve: bool = True,
time_to_run: int = 60 * 60 * 10,
time_to_run: str = "10h",
ratio: float = 0.1,
start_date: datetime.datetime = "2026-09-07",
weeks: int = 26,
@@ -567,8 +589,8 @@ def main(
# Rota.build_workers()
# Rota.build_model()
solver_options = {"ratio": ratio, "seconds": time_to_run, "threads": 10}
# solver_options = {"seconds": time_to_run, "threads": 10}
seconds_to_run = parse_time_limit(time_to_run)
solver_options = {"ratio": ratio, "seconds": seconds_to_run, "threads": 10}
# start_time = time.time()
Rota.build_and_solve(solver_options, export=True, solve=solve, solver="appsi_highs", export_with_timestamp=True)
+13 -1
View File
@@ -2118,4 +2118,16 @@ def test_shift_dependent_dates_model_definition():
assert len(worker.shift_end_dates) == 1
assert isinstance(worker.shift_end_dates[0], ShiftEndDate)
assert worker.shift_end_dates[0].shift == "a"
assert worker.shift_end_dates[0].end_date == datetime.date(2022, 4, 7)
assert worker.shift_end_dates[0].end_date == datetime.date(2022, 4, 7)
def test_parse_time_limit():
from gen_proc import parse_time_limit
assert parse_time_limit(3600) == 3600
assert parse_time_limit("3600") == 3600
assert parse_time_limit("10h") == 36000
assert parse_time_limit("30m") == 1800
assert parse_time_limit("45s") == 45
assert parse_time_limit(" 1.5h ") == 5400
with pytest.raises(ValueError):
parse_time_limit("invalid")