Skip to content

Commit 2790cd4

Browse files
authored
refactor: ♻️ add create_ascii_table utility and update COCO coco_evaluation (#1324)
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
1 parent a8d5e99 commit 2790cd4

4 files changed

Lines changed: 79 additions & 4 deletions

File tree

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ dependencies = [
1313
"pillow>=8.2.0",
1414
"pyyaml",
1515
"fire",
16-
"terminaltables",
1716
"requests",
1817
"click",
1918
"torch>=2.4.1",

sahi/scripts/coco_evaluation.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99

1010
import fire
1111
import numpy as np
12-
from terminaltables import AsciiTable
12+
13+
from sahi.utils.table import create_ascii_table
1314

1415

1516
def _cocoeval_summarize(
@@ -316,8 +317,7 @@ def evaluate_core(
316317
results_2d = itertools.zip_longest(*[results_flatten[i::num_columns] for i in range(num_columns)])
317318
table_data = [headers]
318319
table_data += [result for result in results_2d]
319-
table = AsciiTable(table_data)
320-
print("\n" + table.table)
320+
print("\n" + create_ascii_table(table_data))
321321

322322
if metric_items is None:
323323
metric_items = ["mAP", "mAP50", "mAP75", "mAP_s", "mAP_m", "mAP_l", "mAP50_s", "mAP50_m", "mAP50_l"]

sahi/utils/table.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from __future__ import annotations
2+
3+
from typing import Any
4+
5+
6+
def create_ascii_table(data: list[list[Any]]) -> str:
7+
"""
8+
Creates a clean, properly padded ASCII string grid from a list of lists.
9+
10+
Args:
11+
data (List[List[Any]]): A list of lists representing headers and rows.
12+
13+
Returns:
14+
str: The formatted ASCII table as a string.
15+
"""
16+
if not data or not data[0]:
17+
return ""
18+
19+
# Convert all elements to strings, handling None values as empty strings
20+
str_data = [[str(item) if item is not None else "" for item in row] for row in data]
21+
22+
# Calculate column widths
23+
num_columns = max(len(row) for row in str_data)
24+
col_widths = [0] * num_columns
25+
for row in str_data:
26+
for i, cell in enumerate(row):
27+
if i < num_columns:
28+
col_widths[i] = max(col_widths[i], len(cell))
29+
30+
# Define border part
31+
border = "+" + "+".join("-" * (w + 2) for w in col_widths) + "+"
32+
33+
lines = [border]
34+
for i, row in enumerate(str_data):
35+
padded_row = row + [""] * (num_columns - len(row))
36+
content_row = "| " + " | ".join(cell.ljust(w) for cell, w in zip(padded_row, col_widths)) + " |"
37+
lines.append(content_row)
38+
if i == 0 or i == len(str_data) - 1:
39+
lines.append(border)
40+
41+
return "\n".join(lines)

tests/test_table.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from __future__ import annotations
2+
3+
import unittest
4+
5+
from sahi.utils.table import create_ascii_table
6+
7+
8+
class TestTable(unittest.TestCase):
9+
def test_create_ascii_table_basic(self):
10+
data = [
11+
["Model", "Params(M)", "Dataset"],
12+
["ResNet50", 25.6, "ImageNet"],
13+
["YOLOv8n", 4.5, "COCO"],
14+
["Swin-Transformer", 88.2, "ADE20K"],
15+
]
16+
table = create_ascii_table(data)
17+
18+
# Verify basic structure
19+
self.assertIn("ResNet50", table)
20+
self.assertIn("Dataset", table)
21+
self.assertTrue(table.startswith("+"))
22+
self.assertTrue(table.endswith("+"))
23+
24+
# Verify alignment (Swin-Transformer is the longest model name)
25+
# Content row should contain the full model name padded correctly.
26+
self.assertIn("| Swin-Transformer |", table)
27+
28+
def test_empty_data(self):
29+
self.assertEqual(create_ascii_table([]), "")
30+
self.assertEqual(create_ascii_table([[]]), "")
31+
32+
def test_none_values(self):
33+
data = [["ID", "Value"], [1, None]]
34+
table = create_ascii_table(data)
35+
self.assertIn("| 1 | |", table)

0 commit comments

Comments
 (0)