Skip to content

Commit

Permalink
add property support to sort_by
Browse files Browse the repository at this point in the history
  • Loading branch information
snoyer committed Jan 28, 2025
1 parent 89a09f3 commit bdd11a9
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
5 changes: 4 additions & 1 deletion src/build123d/topology/shape_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2635,7 +2635,7 @@ def solids(self) -> ShapeList[Solid]:

def sort_by(
self,
sort_by: Axis | Callable[[T], K] | Edge | Wire | SortBy = Axis.Z,
sort_by: Axis | Callable[[T], K] | Edge | Wire | SortBy | property = Axis.Z,
reverse: bool = False,
) -> ShapeList[T]:
"""sort by
Expand All @@ -2661,6 +2661,9 @@ def sort_by(
# If a callable is provided, use it directly as the key
objects = sorted(self, key=sort_by, reverse=reverse)

elif isinstance(sort_by, property):
objects = sorted(self, key=sort_by.__get__, reverse=reverse)

elif isinstance(sort_by, Axis):
if sort_by.wrapped is None:
raise ValueError("Cannot sort by an empty axis")
Expand Down
16 changes: 12 additions & 4 deletions tests/test_direct_api/test_shape_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,12 @@ def test_sort_by_lambda(self):
self.assertAlmostEqual(largest.area, math.pi * 2**2, 5)

def test_sort_by_property(self):
box1 = Box(2, 2, 2)
box2 = Box(2, 2, 2).translate((1, 1, 1))
assert len((box1 + box2).edges().filter_by(Edge.is_interior)) == 6
assert len((box1 - box2).edges().filter_by(Edge.is_interior)) == 3
box1 = Box(1, 1, 1)
box2 = Box(2, 2, 2)
box3 = Box(3, 3, 3)
unsorted_boxes = ShapeList([box2, box3, box1])
assert unsorted_boxes.sort_by(Solid.volume) == [box1, box2, box3]
assert unsorted_boxes.sort_by(Solid.volume, reverse=True) == [box3, box2, box1]

def test_sort_by_invalid(self):
with self.assertRaises(ValueError):
Expand Down Expand Up @@ -125,6 +127,12 @@ def test_filter_by_callable_predicate(self):
self.assertEqual(len(shapelist.filter_by(lambda s: s.label == "A")), 2)
self.assertEqual(len(shapelist.filter_by(lambda s: s.label == "B")), 1)

def test_filter_by_property(self):
box1 = Box(2, 2, 2)
box2 = Box(2, 2, 2).translate((1, 1, 1))
assert len((box1 + box2).edges().filter_by(Edge.is_interior)) == 6
assert len((box1 - box2).edges().filter_by(Edge.is_interior)) == 3

def test_first_last(self):
vertices = (
Solid.make_box(1, 1, 1).vertices().sort_by(Axis((0, 0, 0), (1, 1, 1)))
Expand Down

0 comments on commit bdd11a9

Please sign in to comment.