From d3c7d492a921e8dc4499030f2650d0f56290363e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pedro=20L=2E=20Magalh=C3=A3es?= <pmlpm@posteo.de>
Date: Fri, 26 Apr 2024 00:36:14 +0200
Subject: [PATCH] Finished consecutive_qpk method and added respetive tests.

---
 src/topupopt/problems/esipp/time.py |   9 +-
 tests/test_esipp_time.py            | 136 ++++++++++++++++++++++++++++
 2 files changed, 143 insertions(+), 2 deletions(-)

diff --git a/src/topupopt/problems/esipp/time.py b/src/topupopt/problems/esipp/time.py
index 7fc02bb..378483a 100644
--- a/src/topupopt/problems/esipp/time.py
+++ b/src/topupopt/problems/esipp/time.py
@@ -134,8 +134,13 @@ class TimeFrame:
 
     def consecutive_qpk(self, qpk_keyed_dict: dict) -> bool:
         "Returns True if all (q,p,k) tuple keys are valid and consecutive."
-        # TODO: here
-        raise NotImplementedError
+        # all k intervals have to be consecutive for each (q,p) pair
+        set_qp = set(qpk[0:2] for qpk in qpk_keyed_dict.keys())
+        for qp in set_qp:
+            for k in range(self.number_time_intervals(qp[0])):
+                if (*qp,k) not in qpk_keyed_dict:
+                    return False
+        return True
 
     # *************************************************************************
     # *************************************************************************
diff --git a/tests/test_esipp_time.py b/tests/test_esipp_time.py
index 349f270..18bdd01 100644
--- a/tests/test_esipp_time.py
+++ b/tests/test_esipp_time.py
@@ -202,6 +202,28 @@ class TestTimeFrame:
         assert not tf.complete_qpk(
             {(0, 0, 0): 1, (0, 0, 1): 1, (0, 1, 0): 1, (0, 1, 1): 1}
         )
+        # qpk: consecutive
+        assert tf.consecutive_qpk(
+            {
+                (0, 0, 0): 1,
+                (0, 0, 1): 1,
+                (0, 1, 0): 1,
+                (0, 1, 1): 1,
+                (0, 2, 0): 1,
+                (0, 2, 1): 1,
+            }
+        )
+        # qpk: not consecutive
+        assert not tf.consecutive_qpk(
+            {
+                (0, 0, 0): 1,
+                (0, 0, 1): 1,
+                (0, 1, 1): 1,
+                (0, 1, 2): 1,
+                (0, 2, 0): 1,
+                (0, 2, 1): 1,
+            }
+        )
 
         qk_dict = {qk: None for qk in tf.qk()}
         qp_dict = {qp: None for qp in tf.qp()}
@@ -357,6 +379,28 @@ class TestTimeFrame:
         assert not tf.complete_qpk(
             {(0, 0, 0): 1, (0, 0, 1): 1, (1, 1, 0): 1, (1, 1, 1): 1}
         )
+        # qpk: consecutive
+        assert tf.consecutive_qpk(
+            {
+                (0, 0, 0): 1,
+                (0, 0, 1): 1,
+                (1, 1, 0): 1,
+                (1, 1, 1): 1,
+                (1, 2, 0): 1,
+                (1, 2, 1): 1,
+            }
+        )
+        # qpk: not consecutive
+        assert not tf.consecutive_qpk(
+            {
+                (0, 0, 0): 1,
+                (0, 0, 3): 1,
+                (1, 1, 0): 1,
+                (1, 1, 1): 1,
+                (1, 2, 0): 1,
+                (1, 2, 1): 1,
+            }
+        )
 
         qk_dict = {qk: None for qk in tf.qk()}
         qp_dict = {qp: None for qp in tf.qp()}
@@ -507,6 +551,30 @@ class TestTimeFrame:
                 (1, 2, 1): 1,
             }
         )
+        # qpk: consecutive
+        assert tf.consecutive_qpk(
+            {
+                (0, 0, 0): 1,
+                (0, 0, 1): 1,
+                (0, 1, 0): 1,
+                (0, 1, 1): 1,
+                (1, 2, 0): 1,
+                (1, 2, 1): 1,
+                (1, 2, 2): 1,
+            }
+        )
+        # qpk: not consecutive
+        assert not tf.consecutive_qpk(
+            {
+                (0, 0, 0): 1,
+                (0, 0, 1): 1,
+                (0, 1, 0): 1,
+                (0, 1, 1): 1,
+                (1, 2, 0): 1,
+                (1, 2, 1): 1,
+                (1, 2, 3): 1,
+            }
+        )
 
         qk_dict = {qk: None for qk in tf.qk()}
         qp_dict = {qp: None for qp in tf.qp()}
@@ -672,6 +740,40 @@ class TestTimeFrame:
                 (1, 2, 1): 1,
             }
         )
+        # qpk: consecutive
+        assert tf.consecutive_qpk(
+            {
+                (0, 0, 0): 1,
+                (0, 0, 1): 1,
+                (0, 1, 0): 1,
+                (0, 1, 1): 1,
+                (0, 2, 0): 1,
+                (0, 2, 1): 1,
+                (1, 0, 0): 1,
+                (1, 0, 1): 1,
+                (1, 1, 0): 1,
+                (1, 1, 1): 1,
+                (1, 2, 0): 1,
+                (1, 2, 1): 1,
+            }
+        )
+        # qpk: not consecutive
+        assert not tf.consecutive_qpk(
+            {
+                (0, 0, 0): 1,
+                (0, 0, 1): 1,
+                (0, 1, 0): 1,
+                (0, 1, 1): 1,
+                (0, 2, 0): 1,
+                (0, 2, 2): 1,
+                (1, 0, 0): 1,
+                (1, 0, 1): 1,
+                (1, 1, 0): 1,
+                (1, 1, 1): 1,
+                (1, 2, 0): 1,
+                (1, 2, 1): 1,
+            }
+        )
 
         qk_dict = {qk: None for qk in tf.qk()}
         qp_dict = {qp: None for qp in tf.qp()}
@@ -905,6 +1007,40 @@ class TestTimeFrame:
                 # (5, 2, 1): 1,
             }
         )
+        # qpk: consecutive
+        assert tf.consecutive_qpk(
+            {
+                (0, 0, 0): 1,
+                (1, 0, 0): 1,
+                (2, 1, 0): 1,
+                (3, 1, 0): 1,
+                (4, 2, 0): 1,
+                (5, 2, 0): 1,
+                (0, 0, 1): 1,
+                (1, 0, 1): 1,
+                (2, 1, 1): 1,
+                (3, 1, 1): 1,
+                (4, 2, 1): 1,
+                (5, 2, 1): 1,
+            }
+        )
+        # qpk: not consecutive
+        assert not tf.consecutive_qpk(
+            {
+                (0, 0, 0): 1,
+                (1, 0, 0): 1,
+                (2, 1, 0): 1,
+                (3, 1, 0): 1,
+                (4, 2, 0): 1,
+                (5, 2, 0): 1,
+                (0, 0, 2): 1,
+                (1, 0, 1): 1,
+                (2, 1, 1): 1,
+                (3, 1, 1): 1,
+                (4, 2, 1): 1,
+                (5, 2, 1): 1,
+            }
+        )
 
         qk_dict = {qk: None for qk in tf.qk()}
         qp_dict = {qp: None for qp in tf.qp()}
-- 
GitLab