Skip to content

104 Add Grid model and segment_strokes utility function #123

Open
kimit0310 wants to merge 3 commits into
mainfrom
104-add-grid-model-and-utility
Open

104 Add Grid model and segment_strokes utility function #123
kimit0310 wants to merge 3 commits into
mainfrom
104-add-grid-model-and-utility

Conversation

@kimit0310
Copy link
Copy Markdown
Collaborator

@kimit0310 kimit0310 commented Apr 8, 2026

Summary

Adds a Grid dataclass to models.py and a segment_strokes() in alphabet_utils.py. Grid owns a list of GridCell objects and provides a from_bbox factory for subdivision and get_cell_for_point for lookup. segment_strokes() groups drawing data by line_number, creates Stroke objects, and assigns each to a cell by centroid.

Notes

  • from_bbox pads the outer grid edges by a small amount (default 0.1) so that centroids landing exactly on the boundaries are not excluded
  • Strokes whose centroids fall outside the grid are silently dropped

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 8, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.23%. Comparing base (d4a7571) to head (c8818d1).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #123      +/-   ##
==========================================
+ Coverage   98.16%   98.23%   +0.07%     
==========================================
  Files          19       20       +1     
  Lines        1145     1191      +46     
==========================================
+ Hits         1124     1170      +46     
  Misses         21       21              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kimit0310 kimit0310 marked this pull request as ready for review April 8, 2026 14:00
@Asanto32 Asanto32 requested a review from cgmaiorano April 10, 2026 17:53
@Asanto32 Asanto32 requested review from Asanto32 and removed request for cgmaiorano May 21, 2026 15:13
Copy link
Copy Markdown
Collaborator

@Asanto32 Asanto32 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small comments, please look over the tests.
The major concern is about how padding is impacting col width/row height. I think you missed this because you only tested 2x2

)


@dataclasses.dataclass
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still feel like this is a potential future refactor point, too many of these dataclasses feel like regular classes (not just for data storage)

y_max: float,
n_rows: int,
n_cols: int,
labels: Optional[List[str]] = None,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should labels be optional?

padded_y_min = y_min - padding
padded_y_max = y_max + padding

col_width = (padded_x_max - padded_x_min) / n_cols
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you take the padding into effect for the col/row size? it should only be for the start/ends correct? this padding was just for when a centroid lands on the outer boundary?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Run this example and check: 3x3 grid, from [0,30] for x,y. now check you cell_x_min and cell_x_max for row,cols (1,2)

y_max: Top boundary of the grid bounding box.
n_rows: Number of rows in the grid.
n_cols: Number of columns in the grid.
labels: Optional list of labels for each cell in row-major order.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As before should this be optional?


for line_number, group in data.groupby("line_number"):
stroke = models.Stroke(
points=group.reset_index(drop=True),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does reset_index do here?

assert total_strokes == 3

def test_stroke_points_are_correct(self) -> None:
"""Each Stroke should contain the correct subset of points."""
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this only tests one stroke

Comment thread tests/unit/test_grid.py
from graphomotor.core import models


class TestGridFromBbox:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once again why the class here?

Comment thread tests/unit/test_grid.py
)

assert len(grid.cells) == 1
cell = grid.cells[0]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this after an assert?

Comment thread tests/unit/test_grid.py
assert grid.cells[0].y_min > grid.cells[2].y_min
assert grid.cells[0].x_min < grid.cells[1].x_min

def test_labels_assigned(self) -> None:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these first three tests should all be combined probably

Comment thread tests/unit/test_grid.py
"""Tests for Grid.get_cell_for_point."""

@pytest.fixture
def grid_2x2(self) -> models.Grid:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be nice to make this extensible to NxN...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants