From a6b5fd74e797ce94ee4e5132286ce6cd3673ab6a Mon Sep 17 00:00:00 2001 From: Tushar Saini Date: Thu, 16 May 2024 20:21:35 +0530 Subject: [PATCH 1/2] [ADD] add tests --- .github/workflows/test.yml | 26 +++++++ README.md | 8 +-- tests/test_data/neighbors_output.json | 12 ++++ tests/test_data/neighbors_wa_output.json | 12 ++++ ..._ideal_test_data.json => tblr_output.json} | 0 .../{ideal_test_data.json => test_data.json} | 0 tests/test_neighbor.py | 70 +++++++++++++++++++ tests/{tests.py => test_tblr.py} | 24 +++---- tests/test_wa.py | 70 +++++++++++++++++++ 9 files changed, 206 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/test.yml create mode 100644 tests/test_data/neighbors_output.json create mode 100644 tests/test_data/neighbors_wa_output.json rename tests/test_data/{output_ideal_test_data.json => tblr_output.json} (100%) rename tests/test_data/{ideal_test_data.json => test_data.json} (100%) create mode 100644 tests/test_neighbor.py rename tests/{tests.py => test_tblr.py} (78%) create mode 100644 tests/test_wa.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..81704ec --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,26 @@ +name: Run Tests + +on: + push: + branches: main + pull_request: + branches: main + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.x + + - name: Install dependencies + run: pip install -r requirements.txt + + - name: Run tests + run: python -m unittest diff --git a/README.md b/README.md index 7edda2f..fa9dd50 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,10 @@ from retailtree.utils.dist_func import manhattan, euclidean # Create annotation object ann1 = Annotation(id=1, x_min=2, y_min=1, x_max=3, y_max=2) - ann2 = Annotation(id=2, x_min=1, y_min=2, x_max=2, y_max=3) - ann3 = Annotation(id=3, x_min=2, y_min=2, x_max=3, y_max=3) - ann4 = Annotation(id=4, x_min=3, y_min=2, x_max=4, y_max=3) - ann5 = Annotation(id=5, x_min=2, y_min=3, x_max=3, y_max=4) +ann2 = Annotation(id=2, x_min=1, y_min=2, x_max=2, y_max=3) +ann3 = Annotation(id=3, x_min=2, y_min=2, x_max=3, y_max=3) +ann4 = Annotation(id=4, x_min=3, y_min=2, x_max=4, y_max=3) +ann5 = Annotation(id=5, x_min=2, y_min=3, x_max=3, y_max=4) annotations = [ann1, ann2, ann3, ann4, ann5] diff --git a/tests/test_data/neighbors_output.json b/tests/test_data/neighbors_output.json new file mode 100644 index 0000000..9bbad53 --- /dev/null +++ b/tests/test_data/neighbors_output.json @@ -0,0 +1,12 @@ +[ + [{"id": 1, "distance": 90.0}, {"id": 4, "distance": 50.0}, {"id": 5, "distance": 102.95630140987001}], + [{"id": 0, "distance": 90.0}, {"id": 24, "distance": 90.0}, {"id": 6, "distance": 102.95630140987001}, {"id": 4, "distance": 102.95630140987001}, {"id": 5, "distance": 50.0}, {"id": 2, "distance": 90.0}], + [{"id": 7, "distance": 102.95630140987001}, {"id": 3, "distance": 90.0}, {"id": 6, "distance": 50.0}, {"id": 1, "distance": 90.0}, {"id": 25, "distance": 90.0}, {"id": 5, "distance": 102.95630140987001}], + [{"id": 7, "distance": 50.0}, {"id": 6, "distance": 102.95630140987001}, {"id": 2, "distance": 90.0}], + [{"id": 0, "distance": 50.0}, {"id": 1, "distance": 102.95630140987001}, {"id": 24, "distance": 98.48857801796105}, {"id": 5, "distance": 90.0}], + [{"id": 0, "distance": 102.95630140987001}, {"id": 24, "distance": 40.0}, {"id": 6, "distance": 90.0}, {"id": 1, "distance": 50.0}, {"id": 25, "distance": 98.48857801796105}, {"id": 4, "distance": 90.0}, {"id": 2, "distance": 102.95630140987001}], + [{"id": 7, "distance": 90.0}, {"id": 24, "distance": 98.48857801796105}, {"id": 3, "distance": 102.95630140987001}, {"id": 25, "distance": 40.0}, {"id": 5, "distance": 90.0}, {"id": 1, "distance": 102.95630140987001}, {"id": 2, "distance": 50.0}], + [{"id": 3, "distance": 50.0}, {"id": 6, "distance": 90.0}, {"id": 2, "distance": 102.95630140987001}, {"id": 25, "distance": 98.48857801796105}], + [{"id": 26, "distance": 90.0}, {"id": 13, "distance": 102.95630140987001}, {"id": 12, "distance": 50.0}, {"id": 9, "distance": 90.0}], + [{"id": 24, "distance": 70.0}, {"id": 13, "distance": 50.0}, {"id": 12, "distance": 102.95630140987001}, {"id": 8, "distance": 90.0}, {"id": 14, "distance": 102.95630140987001}, {"id": 10, "distance": 90.0}] +] diff --git a/tests/test_data/neighbors_wa_output.json b/tests/test_data/neighbors_wa_output.json new file mode 100644 index 0000000..07b8dc6 --- /dev/null +++ b/tests/test_data/neighbors_wa_output.json @@ -0,0 +1,12 @@ +[ + [{"id": 1, "distance": 90.0, "angle": 0}, {"id": 4, "distance": 50.0, "angle": 90}, {"id": 5, "distance": 102.95630140987001, "angle": 29}], + [{"id": 0, "distance": 90.0, "angle": 180}, {"id": 24, "distance": 90.0, "angle": 90}, {"id": 6, "distance": 102.95630140987001, "angle": 29}, {"id": 4, "distance": 102.95630140987001, "angle": 150}, {"id": 5, "distance": 50.0, "angle": 90}, {"id": 2, "distance": 90.0, "angle": 0}], + [{"id": 7, "distance": 102.95630140987001, "angle": 29}, {"id": 3, "distance": 90.0, "angle": 0}, {"id": 6, "distance": 50.0, "angle": 90}, {"id": 1, "distance": 90.0, "angle": 180}, {"id": 25, "distance": 90.0, "angle": 90}, {"id": 5, "distance": 102.95630140987001, "angle": 150}], + [{"id": 7, "distance": 50.0, "angle": 90}, {"id": 6, "distance": 102.95630140987001, "angle": 150}, {"id": 2, "distance": 90.0, "angle": 180}], + [{"id": 0, "distance": 50.0, "angle": 270}, {"id": 24, "distance": 98.48857801796105, "angle": 23}, {"id": 5, "distance": 90.0, "angle": 0}], + [{"id": 0, "distance": 102.95630140987001, "angle": 210}, {"id": 24, "distance": 40.0, "angle": 90}, {"id": 6, "distance": 90.0, "angle": 0}, {"id": 1, "distance": 50.0, "angle": 270}, {"id": 25, "distance": 98.48857801796105, "angle": 23}, {"id": 4, "distance": 90.0, "angle": 180}], + [{"id": 7, "distance": 90.0, "angle": 0}, {"id": 24, "distance": 98.48857801796105, "angle": 156}, {"id": 25, "distance": 40.0, "angle": 90}, {"id": 5, "distance": 90.0, "angle": 180}, {"id": 1, "distance": 102.95630140987001, "angle": 210}, {"id": 2, "distance": 50.0, "angle": 270}], + [{"id": 3, "distance": 50.0, "angle": 270}, {"id": 6, "distance": 90.0, "angle": 180}, {"id": 2, "distance": 102.95630140987001, "angle": 210}, {"id": 25, "distance": 98.48857801796105, "angle": 156}], + [{"id": 26, "distance": 90.0, "angle": 90}, {"id": 13, "distance": 102.95630140987001, "angle": 29}, {"id": 12, "distance": 50.0, "angle": 90}, {"id": 9, "distance": 90.0, "angle": 0}], + [{"id": 24, "distance": 70.0, "angle": 270}, {"id": 13, "distance": 50.0, "angle": 90}, {"id": 12, "distance": 102.95630140987001, "angle": 150}, {"id": 8, "distance": 90.0, "angle": 180}, {"id": 14, "distance": 102.95630140987001, "angle": 29}, {"id": 10, "distance": 90.0, "angle": 0}] +] diff --git a/tests/test_data/output_ideal_test_data.json b/tests/test_data/tblr_output.json similarity index 100% rename from tests/test_data/output_ideal_test_data.json rename to tests/test_data/tblr_output.json diff --git a/tests/test_data/ideal_test_data.json b/tests/test_data/test_data.json similarity index 100% rename from tests/test_data/ideal_test_data.json rename to tests/test_data/test_data.json diff --git a/tests/test_neighbor.py b/tests/test_neighbor.py new file mode 100644 index 0000000..df1234d --- /dev/null +++ b/tests/test_neighbor.py @@ -0,0 +1,70 @@ +import unittest +from retailtree.retailtree import Annotation, RetailTree +import json + + +class TestAnnotation(unittest.TestCase): + + def setUp(self): + # Build tree before every test case + file_path = './tests/test_data/test_data.json' + file_path_output = './tests/test_data/neighbors_output.json' + # Annotations data2 + with open(file_path, 'r') as file: + self.annotation_data_json = json.load(file) + + with open(file_path_output, 'r') as file: + self.annotation_output_data = json.load(file) + + self.RT = RetailTree() + for data in self.annotation_data_json: + ann = Annotation(data['id'], data['x_min'], + data['y_min'], data['x_max'], data['y_max']) + self.RT.add_annotation(ann) + + self.RT.build_tree() + self.assertIsNotNone(self.RT.tree) + + def test_find_neighbors_0(self): + self.assertEqual(self.RT.neighbors( + id=0, radius=1.2), self.annotation_output_data[0]) + + def test_find_neighbors_1(self): + self.assertEqual(self.RT.neighbors( + id=1, radius=1.2), self.annotation_output_data[1]) + + def test_find_neighbors_2(self): + self.assertEqual(self.RT.neighbors( + id=2, radius=1.2), self.annotation_output_data[2]) + + def test_find_neighbors_3(self): + self.assertEqual(self.RT.neighbors( + id=3, radius=1.2), self.annotation_output_data[3]) + + def test_find_neighbors_4(self): + self.assertEqual(self.RT.neighbors( + id=4, radius=1.2), self.annotation_output_data[4]) + + def test_find_neighbors_5(self): + self.assertEqual(self.RT.neighbors( + id=5, radius=1.2), self.annotation_output_data[5]) + + def test_find_neighbors_6(self): + self.assertEqual(self.RT.neighbors( + id=6, radius=1.2), self.annotation_output_data[6]) + + def test_find_neighbors_7(self): + self.assertEqual(self.RT.neighbors( + id=7, radius=1.2), self.annotation_output_data[7]) + + def test_find_neighbors_8(self): + self.assertEqual(self.RT.neighbors( + id=8, radius=1.2), self.annotation_output_data[8]) + + def test_find_neighbors_9(self): + self.assertEqual(self.RT.neighbors( + id=9, radius=1.2), self.annotation_output_data[9]) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/tests.py b/tests/test_tblr.py similarity index 78% rename from tests/tests.py rename to tests/test_tblr.py index 5593e93..ec34c97 100644 --- a/tests/tests.py +++ b/tests/test_tblr.py @@ -7,8 +7,8 @@ class TestAnnotation(unittest.TestCase): def setUp(self): # Build tree before every test case - file_path = './tests/test_data/ideal_test_data.json' - file_path_output = './tests/test_data/output_ideal_test_data.json' + file_path = './tests/test_data/test_data.json' + file_path_output = './tests/test_data/tblr_output.json' # Annotations data2 with open(file_path, 'r') as file: self.annotation_data_json = json.load(file) @@ -25,43 +25,43 @@ def setUp(self): self.RT.build_tree() self.assertIsNotNone(self.RT.tree) - def test_find_neighbors_0(self): + def test_tblr_0(self): self.assertEqual(self.RT.TBLR( id=0, radius=2), self.annotation_output_data[0]) - def test_find_neighbors_1(self): + def test_tblr_1(self): self.assertEqual(self.RT.TBLR( id=1, radius=2), self.annotation_output_data[1]) - def test_find_neighbors_2(self): + def test_tblr_2(self): self.assertEqual(self.RT.TBLR( id=2, radius=2), self.annotation_output_data[2]) - def test_find_neighbors_3(self): + def test_tblr_3(self): self.assertEqual(self.RT.TBLR( id=3, radius=2), self.annotation_output_data[3]) - def test_find_neighbors_4(self): + def test_tblr_4(self): self.assertEqual(self.RT.TBLR( id=4, radius=2), self.annotation_output_data[4]) - def test_find_neighbors_5(self): + def test_tblr_5(self): self.assertEqual(self.RT.TBLR( id=5, radius=2), self.annotation_output_data[5]) - def test_find_neighbors_6(self): + def test_tblr_6(self): self.assertEqual(self.RT.TBLR( id=6, radius=2), self.annotation_output_data[6]) - def test_find_neighbors_7(self): + def test_tblr_7(self): self.assertEqual(self.RT.TBLR( id=7, radius=2), self.annotation_output_data[7]) - def test_find_neighbors_8(self): + def test_tblr_8(self): self.assertEqual(self.RT.TBLR( id=8, radius=2), self.annotation_output_data[8]) - def test_find_neighbors_9(self): + def test_tblr_9(self): self.assertEqual(self.RT.TBLR( id=9, radius=2), self.annotation_output_data[9]) diff --git a/tests/test_wa.py b/tests/test_wa.py new file mode 100644 index 0000000..4f4d7d6 --- /dev/null +++ b/tests/test_wa.py @@ -0,0 +1,70 @@ +import unittest +from retailtree.retailtree import Annotation, RetailTree +import json + + +class TestAnnotation(unittest.TestCase): + + def setUp(self): + # Build tree before every test case + file_path = './tests/test_data/test_data.json' + file_path_output = './tests/test_data/neighbors_wa_output.json' + # Annotations data2 + with open(file_path, 'r') as file: + self.annotation_data_json = json.load(file) + + with open(file_path_output, 'r') as file: + self.annotation_output_data = json.load(file) + + self.RT = RetailTree() + for data in self.annotation_data_json: + ann = Annotation(data['id'], data['x_min'], + data['y_min'], data['x_max'], data['y_max']) + self.RT.add_annotation(ann) + + self.RT.build_tree() + self.assertIsNotNone(self.RT.tree) + + def test_find_neighbors_0(self): + self.assertEqual(self.RT.neighbors_wa( + id=0, radius=1.2, amin=0, amax=270), self.annotation_output_data[0]) + + def test_find_neighbors_1(self): + self.assertEqual(self.RT.neighbors_wa( + id=1, radius=1.2, amin=0, amax=270), self.annotation_output_data[1]) + + def test_find_neighbors_2(self): + self.assertEqual(self.RT.neighbors_wa( + id=2, radius=1.2, amin=0, amax=270), self.annotation_output_data[2]) + + def test_find_neighbors_3(self): + self.assertEqual(self.RT.neighbors_wa( + id=3, radius=1.2, amin=0, amax=270), self.annotation_output_data[3]) + + def test_find_neighbors_4(self): + self.assertEqual(self.RT.neighbors_wa( + id=4, radius=1.2, amin=0, amax=270), self.annotation_output_data[4]) + + def test_find_neighbors_5(self): + self.assertEqual(self.RT.neighbors_wa( + id=5, radius=1.2, amin=0, amax=270), self.annotation_output_data[5]) + + def test_find_neighbors_6(self): + self.assertEqual(self.RT.neighbors_wa( + id=6, radius=1.2, amin=0, amax=270), self.annotation_output_data[6]) + + def test_find_neighbors_7(self): + self.assertEqual(self.RT.neighbors_wa( + id=7, radius=1.2, amin=0, amax=270), self.annotation_output_data[7]) + + def test_find_neighbors_8(self): + self.assertEqual(self.RT.neighbors_wa( + id=8, radius=1.2, amin=0, amax=270), self.annotation_output_data[8]) + + def test_find_neighbors_9(self): + self.assertEqual(self.RT.neighbors_wa( + id=9, radius=1.2, amin=0, amax=270), self.annotation_output_data[9]) + + +if __name__ == '__main__': + unittest.main() From abffc29d06ca915414c01ac26ee70eb968d0d3b0 Mon Sep 17 00:00:00 2001 From: Tushar Saini Date: Fri, 17 May 2024 11:40:15 +0530 Subject: [PATCH 2/2] [UPD] update readme.md --- README.md | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index fa9dd50..ce0f922 100644 --- a/README.md +++ b/README.md @@ -21,39 +21,42 @@ pip install retailtree # Usage ``` +# Import necessary modules and functions from retailtree import RetailTree, Annotation from retailtree.utils.dist_func import manhattan, euclidean +import json -# Create annotation object -ann1 = Annotation(id=1, x_min=2, y_min=1, x_max=3, y_max=2) -ann2 = Annotation(id=2, x_min=1, y_min=2, x_max=2, y_max=3) -ann3 = Annotation(id=3, x_min=2, y_min=2, x_max=3, y_max=3) -ann4 = Annotation(id=4, x_min=3, y_min=2, x_max=4, y_max=3) -ann5 = Annotation(id=5, x_min=2, y_min=3, x_max=3, y_max=4) +# Define the path to the JSON file containing annotations +file_path = './tests/test_data/test_data.json' -annotations = [ann1, ann2, ann3, ann4, ann5] +# Open and load the JSON file +with open(file_path, 'r') as file: + annotations = json.load(file) -# Create retailtree object +# Initialize a RetailTree object rt = RetailTree() -# Adding annotations to retailtree +# Iterate over the loaded annotations and create Annotation objects for ann in annotations: - rt.add_annotation(ann) + # Create an Annotation object with the required properties + ann_obj = Annotation(id=ann['id'], x_min=ann['x_min'], y_min=ann['y_min'], x_max=ann['x_max'], y_max=ann['y_max']) + # Add the created Annotation object to the RetailTree + rt.add_annotation(ann_obj) - -# Build tree +# Build the spatial tree structure using the euclidean distance function rt.build_tree(dist_func=euclidean) -# Get neighbors-annotations within radius +# Retrieve and print annotations within a radius of 1 from the annotation with id=3 print(rt.neighbors(id=3, radius=1)) -# Get Top, Bottom, Right, Left annotations +# Retrieve and print the Top, Bottom, Left, and Right neighboring annotations +# of the annotation with id=3 within a radius of 1 and a minimum overlap of 0.5 print(rt.TBLR(id=3, radius=1, overlap=0.5)) -# Get neighboring annotations within a particular angle range +# Retrieve and print neighboring annotations of the annotation with id=3 +# within a radius of 1 and angle range from 0 to 180 degrees print(rt.neighbors_wa(id=3, radius=1, amin=0, amax=180)) -# Get annotation properties +# Retrieve and print the coordinates of the annotation with id=3 print(rt.get(id=3).get_coords()) - ```