I have a type alias that I call point2d
and a related recursive type alias.
<code>point2d = tuple[float, float]
point2d_nested = (
point2d
| list["point2d_nested"]
| tuple["point2d_nested", ...]
)
</code>
<code>point2d = tuple[float, float]
point2d_nested = (
point2d
| list["point2d_nested"]
| tuple["point2d_nested", ...]
)
</code>
point2d = tuple[float, float]
point2d_nested = (
point2d
| list["point2d_nested"]
| tuple["point2d_nested", ...]
)
Now I want to write a function that will scale points in any nested structure by a factor. For example, scale_nested((1,1), 2) == (2,2)
or scale_nested([(1,1), (1,1)]) == [(2,2), (2,2)]
. Here’s an implementation:
<code>def scale_nested(points: point2d_nested, factor: float) -> point2d_nested:
"""
Scales a list of lists of points by a given factor.
Weird things happen if you supply 3D points or if your point is not a tuple.
"""
if not points:
return points
# We've bottomed out at a point
if (
isinstance(points, tuple)
and len(points) == 2
and isinstance(points[0], (int, float))
and isinstance(points[1], (int, float))
):
return points[0] * factor, points[1] * factor
if isinstance(points, list):
return [scale_nested(p, factor) for p in points]
if isinstance(points, tuple):
return tuple(
scale_nested(p, factor) for p in points if not isinstance(p, (int, float))
)
raise ValueError(f"Something is an invalid type: {points}")
</code>
<code>def scale_nested(points: point2d_nested, factor: float) -> point2d_nested:
"""
Scales a list of lists of points by a given factor.
Weird things happen if you supply 3D points or if your point is not a tuple.
"""
if not points:
return points
# We've bottomed out at a point
if (
isinstance(points, tuple)
and len(points) == 2
and isinstance(points[0], (int, float))
and isinstance(points[1], (int, float))
):
return points[0] * factor, points[1] * factor
if isinstance(points, list):
return [scale_nested(p, factor) for p in points]
if isinstance(points, tuple):
return tuple(
scale_nested(p, factor) for p in points if not isinstance(p, (int, float))
)
raise ValueError(f"Something is an invalid type: {points}")
</code>
def scale_nested(points: point2d_nested, factor: float) -> point2d_nested:
"""
Scales a list of lists of points by a given factor.
Weird things happen if you supply 3D points or if your point is not a tuple.
"""
if not points:
return points
# We've bottomed out at a point
if (
isinstance(points, tuple)
and len(points) == 2
and isinstance(points[0], (int, float))
and isinstance(points[1], (int, float))
):
return points[0] * factor, points[1] * factor
if isinstance(points, list):
return [scale_nested(p, factor) for p in points]
if isinstance(points, tuple):
return tuple(
scale_nested(p, factor) for p in points if not isinstance(p, (int, float))
)
raise ValueError(f"Something is an invalid type: {points}")
Unfortunately, this doesn’t work:
<code>knots = [((1.0, 2.0),)]
scale_nested(knots, 2) # <- knots look red
</code>
<code>knots = [((1.0, 2.0),)]
scale_nested(knots, 2) # <- knots look red
</code>
knots = [((1.0, 2.0),)]
scale_nested(knots, 2) # <- knots look red
<code>Argument of type "list[tuple[tuple[float, float]]]" cannot be assigned to parameter "points" of type "point2d_nested" in function "scale_nested"
Type "list[tuple[tuple[float, float]]]" cannot be assigned to type "point2d_nested"
"list[tuple[tuple[float, float]]]" is incompatible with "point2d"
"list[tuple[tuple[float, float]]]" is incompatible with "list[point2d_nested]"
Type parameter "_T@list" is invariant, but "tuple[tuple[float, float]]" is not the same as "point2d_nested"
Consider switching from "list" to "Sequence" which is covariant
"list[tuple[tuple[float, float]]]" is incompatible with "tuple[point2d_nested, ...]"PylancereportGeneralTypeIssues
(variable) knots: list[tuple[tuple[float, float]]]
</code>
<code>Argument of type "list[tuple[tuple[float, float]]]" cannot be assigned to parameter "points" of type "point2d_nested" in function "scale_nested"
Type "list[tuple[tuple[float, float]]]" cannot be assigned to type "point2d_nested"
"list[tuple[tuple[float, float]]]" is incompatible with "point2d"
"list[tuple[tuple[float, float]]]" is incompatible with "list[point2d_nested]"
Type parameter "_T@list" is invariant, but "tuple[tuple[float, float]]" is not the same as "point2d_nested"
Consider switching from "list" to "Sequence" which is covariant
"list[tuple[tuple[float, float]]]" is incompatible with "tuple[point2d_nested, ...]"PylancereportGeneralTypeIssues
(variable) knots: list[tuple[tuple[float, float]]]
</code>
Argument of type "list[tuple[tuple[float, float]]]" cannot be assigned to parameter "points" of type "point2d_nested" in function "scale_nested"
Type "list[tuple[tuple[float, float]]]" cannot be assigned to type "point2d_nested"
"list[tuple[tuple[float, float]]]" is incompatible with "point2d"
"list[tuple[tuple[float, float]]]" is incompatible with "list[point2d_nested]"
Type parameter "_T@list" is invariant, but "tuple[tuple[float, float]]" is not the same as "point2d_nested"
Consider switching from "list" to "Sequence" which is covariant
"list[tuple[tuple[float, float]]]" is incompatible with "tuple[point2d_nested, ...]"PylancereportGeneralTypeIssues
(variable) knots: list[tuple[tuple[float, float]]]