From 252f3a824eca31b3a6909136b1e48a1ba0367f61 Mon Sep 17 00:00:00 2001 From: Trolli Schmittlauch Date: Sat, 8 Jul 2017 02:19:34 +0200 Subject: [PATCH 1/3] JobShopProblem is now a Mapping, not a list - implementing all interface functions for JobShopProblem to behave like a Mapping (e.g. dict) with (int, int) keys this implements and closes #14 --- src/Parser/__init__.py | 35 ++++++++++++++++++++++++++++++++--- src/Parser/js1_style.py | 2 +- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/Parser/__init__.py b/src/Parser/__init__.py index c463b13..85b3742 100644 --- a/src/Parser/__init__.py +++ b/src/Parser/__init__.py @@ -1,6 +1,7 @@ -from typing import List, Tuple +from typing import List, Tuple, Generator import arpeggio from itertools import chain +from collections.abc import Mapping __all__ = ["js1_style", "js2_style"] @@ -43,7 +44,7 @@ class ParseError(Exception): self.message = message -class JobShopProblem(list): +class JobShopProblem(Mapping): def __init__( self, jobs: int, machines: int, @@ -59,11 +60,39 @@ class JobShopProblem(list): self.name = name self.machines = machines self.jobs = jobs - super().__init__(problem_data) + self.problem_data = problem_data def __str__(self) -> str: return "JobShopProblem " + str(self.name) + # make this behave like a mapping (e.g. a dict) + def __getitem__(self, key: Tuple[int, int]) -> Tuple[int, int]: + try: + # unpacking key + (jobnum, tasknum) = key + return self.problem_data[jobnum][tasknum] + except ValueError as e: + raise TypeError("Key must be a (int, int) tuple") + + def __iter__(self): + self.iterpos1 = 0 + self.iterpos2 = 0 + return self + + def __next__(self) -> Tuple[int, int]: + if self.iterpos1 >= len(self.problem_data): + raise StopIteration + return_key = (self.iterpos1, self.iterpos2) + self.iterpos2 += 1 + if self.iterpos2 >= len(self.problem_data[self.iterpos1]): + self.iterpos2 = 0 + self.iterpos1 += 1 + return return_key + + + def __len__(self) -> int: + return sum(map(len, self.problem_data)) + class JobShopVisitor(arpeggio.PTNodeVisitor): """contains visitor functions needed for both jobshop1 (list of instances) diff --git a/src/Parser/js1_style.py b/src/Parser/js1_style.py index 1d4906e..6e5e81d 100644 --- a/src/Parser/js1_style.py +++ b/src/Parser/js1_style.py @@ -45,7 +45,7 @@ class JobShop1Visitor(JobShopVisitor): return None -def parse_string(inputdata: str) -> JobShopProblem: +def parse_string(inputdata: str) -> List[JobShopProblem]: """parse string with jobshop1-formatted data (multiple problem instances) and return list of JobShopProblem s""" parse_tree = parser.parse(inputdata) From 4204969da9580310ad019768dd88a7897c910618 Mon Sep 17 00:00:00 2001 From: Maximilian Schlosser Date: Sun, 9 Jul 2017 13:15:30 +0200 Subject: [PATCH 2/3] helper method to extract single jobs --- src/Parser/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Parser/__init__.py b/src/Parser/__init__.py index 85b3742..bc4f79a 100644 --- a/src/Parser/__init__.py +++ b/src/Parser/__init__.py @@ -93,6 +93,8 @@ class JobShopProblem(Mapping): def __len__(self) -> int: return sum(map(len, self.problem_data)) + def get_tasks_by_job(self, job): + return self.problem_data[job] class JobShopVisitor(arpeggio.PTNodeVisitor): """contains visitor functions needed for both jobshop1 (list of instances) From ae43bd526424c36c3dc6d904d34d397921646c27 Mon Sep 17 00:00:00 2001 From: Trolli Schmittlauch Date: Sun, 9 Jul 2017 17:20:07 +0200 Subject: [PATCH 3/3] add typing annotations to get_task_by_job --- src/Parser/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Parser/__init__.py b/src/Parser/__init__.py index bc4f79a..d42e09c 100644 --- a/src/Parser/__init__.py +++ b/src/Parser/__init__.py @@ -93,7 +93,7 @@ class JobShopProblem(Mapping): def __len__(self) -> int: return sum(map(len, self.problem_data)) - def get_tasks_by_job(self, job): + def get_tasks_by_job(self, job: int) -> List[Tuple[int, int]]: return self.problem_data[job] class JobShopVisitor(arpeggio.PTNodeVisitor):