From a919530cab64e3b2d4dfe412bf63c73db6ae8457 Mon Sep 17 00:00:00 2001 From: Josh Burman Date: Wed, 27 Apr 2022 15:46:23 +0000 Subject: [PATCH 1/4] proper typing and bundle first ordering --- app/helpers/service_helper.py | 13 ++++++++++--- app/models/bundle.py | 3 +++ app/models/item.py | 1 + app/models/solver_run.py | 10 +++++----- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/helpers/service_helper.py b/app/helpers/service_helper.py index cfae641..3617025 100644 --- a/app/helpers/service_helper.py +++ b/app/helpers/service_helper.py @@ -105,6 +105,8 @@ def key_to_uuid(key): def solution_items(variables: list, solver_run: SolverRun) -> Tuple[list]: form_items = [] + form_bundles = [] + final_items = [] solver_variables = [] for v in variables: @@ -120,9 +122,14 @@ def solution_items(variables: list, solver_run: SolverRun) -> Tuple[list]: bundle_id = v.name.replace('Bundle_', '') bundle = solver_run.get_bundle(int(bundle_id)) - if bundle: - for item in bundle.items: - if item: form_items.append(item) + if bundle: form_bundles.append(bundle) + + for bundle in form_bundles: + for item in bundle.ordered_items: + final_items.append(item) + + for item in form_items: + final_items.append(item) return form_items, solver_variables diff --git a/app/models/bundle.py b/app/models/bundle.py index 82fb127..7b15a9f 100644 --- a/app/models/bundle.py +++ b/app/models/bundle.py @@ -46,3 +46,6 @@ class Bundle(BaseModel): total += self.trf(solver_run.irt_model, target.theta) return total + + def ordered_items(self) -> List[Item]: + return sorted(self.items, key=lambda x: x.position) diff --git a/app/models/item.py b/app/models/item.py index 260d612..f9f0a65 100644 --- a/app/models/item.py +++ b/app/models/item.py @@ -8,6 +8,7 @@ from lib.irt.item_information_function import ItemInformationFunction class Item(BaseModel): id: int + position: Optional[int] passage_id: Optional[int] workflow_state: Optional[str] attributes: List[Attribute] diff --git a/app/models/solver_run.py b/app/models/solver_run.py index ad54659..69550d0 100644 --- a/app/models/solver_run.py +++ b/app/models/solver_run.py @@ -14,7 +14,7 @@ from models.advanced_options import AdvancedOptions class SolverRun(BaseModel): items: List[Item] = [] - bundles: list[Bundle] = [] + bundles: List[Bundle] = [] constraints: List[Constraint] irt_model: IRTModel objective_function: ObjectiveFunction @@ -40,7 +40,7 @@ class SolverRun(BaseModel): if type == constraint.reference_attribute.type: return constraint - def remove_items(self, items: list[Item]) -> bool: + def remove_items(self, items: List[Item]) -> bool: self.items = [item for item in self.items if item not in items] return True @@ -100,7 +100,7 @@ class SolverRun(BaseModel): return next((constraint for constraint in self.constraints if constraint.reference_attribute.id == name), None) - def unbundled_items(self) -> list: + def unbundled_items(self) -> List[Item]: # since the only bundles are based on passage id currently # in the future when we have more than just passage based bundles # we'll need to develop a more sophisticated way of handling this concern @@ -113,7 +113,7 @@ class SolverRun(BaseModel): else: return self.items - def select_items_by_percent(self, percent: int) -> list[Item]: + def select_items_by_percent(self, percent: int) -> List[Item]: items = self.unbundled_items() total_items = len(items) selected_items_amount = round(total_items - (total_items * @@ -121,7 +121,7 @@ class SolverRun(BaseModel): return random.sample(items, selected_items_amount) - def select_bundles_by_percent(self, percent: int) -> list[Bundle]: + def select_bundles_by_percent(self, percent: int) -> List[Bundle]: total_bundles = len(self.bundles) selected_bundles_amount = round(total_bundles - (total_bundles * (percent / 100))) From a3ca2339538eb08c82e2c57ebc1e179da947bb6e Mon Sep 17 00:00:00 2001 From: Josh Burman Date: Wed, 27 Apr 2022 15:54:59 +0000 Subject: [PATCH 2/4] enforce bundle first ordering if bundles ordering is true --- app/helpers/service_helper.py | 3 ++- app/models/solver_run.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/helpers/service_helper.py b/app/helpers/service_helper.py index 3617025..8acd664 100644 --- a/app/helpers/service_helper.py +++ b/app/helpers/service_helper.py @@ -125,7 +125,8 @@ def solution_items(variables: list, solver_run: SolverRun) -> Tuple[list]: if bundle: form_bundles.append(bundle) for bundle in form_bundles: - for item in bundle.ordered_items: + items = bundle.ordered_items if solver_run.bundle_first_ordering else bundle.items + for item in items: final_items.append(item) for item in form_items: diff --git a/app/models/solver_run.py b/app/models/solver_run.py index 69550d0..79eb9ed 100644 --- a/app/models/solver_run.py +++ b/app/models/solver_run.py @@ -15,6 +15,7 @@ from models.advanced_options import AdvancedOptions class SolverRun(BaseModel): items: List[Item] = [] bundles: List[Bundle] = [] + bundle_first_ordering: bool = True constraints: List[Constraint] irt_model: IRTModel objective_function: ObjectiveFunction From 35a5ab061b8d0cc8ec0993087ecf8599d6469244 Mon Sep 17 00:00:00 2001 From: Josh Burman Date: Wed, 27 Apr 2022 16:03:14 +0000 Subject: [PATCH 3/4] final items need to be returned --- app/helpers/service_helper.py | 2 +- app/services/loft_service.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/helpers/service_helper.py b/app/helpers/service_helper.py index 8acd664..7f74d1e 100644 --- a/app/helpers/service_helper.py +++ b/app/helpers/service_helper.py @@ -132,7 +132,7 @@ def solution_items(variables: list, solver_run: SolverRun) -> Tuple[list]: for item in form_items: final_items.append(item) - return form_items, solver_variables + return final_items, solver_variables def print_problem_variables(problem): # Uncomment this as needed in local dev diff --git a/app/services/loft_service.py b/app/services/loft_service.py index d854291..0174158 100644 --- a/app/services/loft_service.py +++ b/app/services/loft_service.py @@ -83,11 +83,11 @@ class LoftService(Base): lowBound=0, upBound=1, cat='Binary') - bundles = LpVariable.dicts( - "Bundle", [bundle.id for bundle in selected_bundles], - lowBound=0, - upBound=1, - cat='Binary') + bundles = LpVariable.dicts("Bundle", + [bundle.id for bundle in selected_bundles], + lowBound=0, + upBound=1, + cat='Binary') logging.info(f'Generating Solution for Form {form_number}') From a44a2162b0fea56faf0366aed10d95757b64d4da Mon Sep 17 00:00:00 2001 From: Josh Burman Date: Wed, 27 Apr 2022 18:38:50 +0000 Subject: [PATCH 4/4] make sorted lambda variable more descriptive --- app/models/bundle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/bundle.py b/app/models/bundle.py index 7b15a9f..475d710 100644 --- a/app/models/bundle.py +++ b/app/models/bundle.py @@ -48,4 +48,4 @@ class Bundle(BaseModel): return total def ordered_items(self) -> List[Item]: - return sorted(self.items, key=lambda x: x.position) + return sorted(self.items, key=lambda item: item.position)