From 5bd3eb7b908bb53a317349289fecf661a137cac1 Mon Sep 17 00:00:00 2001
From: Josh Burman <jburman@yas.getyardstick.com>
Date: Sat, 30 Oct 2021 07:15:49 +0000
Subject: [PATCH] added tcc and tif results to form

---
 app/helpers/irt_helper.py    | 22 ++++++++++++++++++++++
 app/models/form.py           | 16 ++++++++++++++++
 app/models/target.py         |  2 ++
 app/services/loft_service.py | 13 ++-----------
 4 files changed, 42 insertions(+), 11 deletions(-)
 create mode 100644 app/helpers/irt_helper.py

diff --git a/app/helpers/irt_helper.py b/app/helpers/irt_helper.py
new file mode 100644
index 0000000..401e875
--- /dev/null
+++ b/app/helpers/irt_helper.py
@@ -0,0 +1,22 @@
+from lib.irt.test_response_function import TestResponseFunction
+from lib.irt.test_information_function import TestInformationFunction
+
+from models.target import Target
+
+def generate_tif_results(items, solver_run):
+  targets = []
+
+  for target in solver_run.objective_function.tif_targets:
+    tif = TestInformationFunction(solver_run.irt_model).calculate(items, theta=target.theta)
+    targets.append(Target(theta=target.theta, value=target.value, result=tif))
+
+  return targets
+
+def generate_tcc_results(items, solver_run):
+  targets = []
+
+  for target in solver_run.objective_function.tcc_targets:
+    tcc = TestResponseFunction(solver_run.irt_model).calculate(items, theta=target.theta)
+    targets.append(Target(theta=target.theta, value=target.value, result=tcc))
+
+  return targets
diff --git a/app/models/form.py b/app/models/form.py
index 57b4e50..cae4073 100644
--- a/app/models/form.py
+++ b/app/models/form.py
@@ -1,8 +1,24 @@
 from pydantic import BaseModel
 from typing import List
 
+from helpers import irt_helper
+
 from models.item import Item
+from models.target import Target
+
+from lib.irt.test_response_function import TestResponseFunction
 
 class Form(BaseModel):
   items: List[Item]
   cut_score: float
+  tif_results: List[Target]
+  tcc_results: List[Target]
+
+  @classmethod
+  def create(cls, items, solver_run):
+    return cls(
+      items=items,
+      cut_score=TestResponseFunction(solver_run.irt_model).calculate(items, theta=solver_run.theta_cut_score),
+      tif_results=irt_helper.generate_tif_results(items, solver_run),
+      tcc_results=irt_helper.generate_tcc_results(items, solver_run)
+    )
diff --git a/app/models/target.py b/app/models/target.py
index 1383208..3999d83 100644
--- a/app/models/target.py
+++ b/app/models/target.py
@@ -1,5 +1,7 @@
 from pydantic import BaseModel
+from typing import Optional
 
 class Target(BaseModel):
   theta: float
   value: float
+  result: Optional[float]
diff --git a/app/services/loft_service.py b/app/services/loft_service.py
index d189958..eee5d6d 100644
--- a/app/services/loft_service.py
+++ b/app/services/loft_service.py
@@ -3,15 +3,12 @@ import json
 import random
 import io
 
-from helpers import aws_helper, tar_helper, csv_helper, service_helper
+from helpers import aws_helper, tar_helper, csv_helper, service_helper, irt_helper
 
 from models.solver_run import SolverRun
 from models.solution import Solution
 from models.form import Form
 
-from lib.irt.test_response_function import TestResponseFunction
-from lib.irt.test_information_function import TestInformationFunction
-
 from services.base import Base
 
 class LoftService(Base):
@@ -48,7 +45,7 @@ class LoftService(Base):
     # real solver will return N forms and process a cut score, this is for mock purposes
     return Solution(
       response_id=random.randint(100,5000),
-      forms=[self.generate_forms(random.sample(self.solver_run.items, self.solver_run.total_form_items)) for x in range(form_count)]
+      forms=[Form.create(random.sample(self.solver_run.items, self.solver_run.total_form_items), self.solver_run) for x in range(form_count)]
     )
 
   def stream_to_s3_bucket(self):
@@ -58,9 +55,3 @@ class LoftService(Base):
 
     # upload generated file to s3 and return result
     return aws_helper.file_stream_upload(solution_file, f'{service_helper.key_to_uuid(self.key)}.csv', os.environ['MEASURE_PROCESSED_BUCKET'])
-
-  def generate_forms(self, items):
-    return Form(
-      items=items,
-      cut_score=TestResponseFunction(self.solver_run.irt_model).calculate(items, theta=self.solver_run.theta_cut_score)
-    )