Skip to content

location

GridType = TypeVar('GridType') module-attribute

LocationTuple = tuple[XLoc, YLoc] module-attribute

PointList = list[Point] module-attribute

ValLocTuple = tuple[XLoc, YLoc, GridType] module-attribute

XLoc = NewType('XLoc', int) module-attribute

YLoc = NewType('YLoc', int) module-attribute

ChangedPoint

Bases: Point

Represents a value changing from old_val to val at a given (x, y) location.

Source code in roc/location.py
 93
 94
 95
 96
 97
 98
 99
100
101
class ChangedPoint(Point):
    """Represents a value changing from `old_val` to `val` at a given (x, y) location."""

    def __init_(self, x: XLoc, y: YLoc, val: int, old_val: int) -> None:
        super().__init__(x, y, val)
        self.old_val = old_val

    def __repr__(self) -> str:
        return f"({self.x}, {self.y}): {self.old_val} '{chr(self.old_val)}' -> {self.val} '{chr(self.val)}'"

__init_(x, y, val, old_val)

Source code in roc/location.py
96
97
98
def __init_(self, x: XLoc, y: YLoc, val: int, old_val: int) -> None:
    super().__init__(x, y, val)
    self.old_val = old_val

__repr__()

Source code in roc/location.py
100
101
def __repr__(self) -> str:
    return f"({self.x}, {self.y}): {self.old_val} '{chr(self.old_val)}' -> {self.val} '{chr(self.val)}'"

DebugGrid

Bases: Grid[GridStyle]

Source code in roc/location.py
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
class DebugGrid(Grid[GridStyle]):
    def __new__(cls, grid: IntGrid) -> DebugGrid:
        # obj = np.ndarray((grid.height, grid.width), dtype=object).view(DebugGrid)
        obj = np.array(
            [
                [
                    GridStyle(
                        front_hue=0,
                        front_saturation=0,
                        front_brightness=1,
                        back_hue=0,
                        back_saturation=1,
                        back_brightness=0,
                        val=chr(grid[row, col]),
                        style="none",
                    )
                    for col in range(grid.width)
                ]
                for row in range(grid.height)
            ]
        ).view(DebugGrid)
        return obj

    def __array_finalize__(self, obj: npt.NDArray[Any] | None) -> None:
        if obj is None:
            return

    # def __init__(self, grid: Grid[Any]) -> None:
    #     width = grid.width
    #     height = grid.height
    #     map: list[list[GridStyle]] = [
    #         [
    #             GridStyle(
    #                 front_hue=0,
    #                 front_saturation=0,
    #                 front_brightness=1,
    #                 back_hue=0,
    #                 back_saturation=1,
    #                 back_brightness=0,
    #                 val=" ",
    #                 style="none",
    #             )
    #             for col in range(width)
    #         ]
    #         for row in range(height)
    #     ]
    #     super().__init__(map)

    #     # copy over all the values from the grid
    #     for p in grid.points():
    #         s = self.get_val(p.x, p.y)
    #         s.val = chr(p.val)

    def set_style(self, x: int, y: int, *, style: str | None = None, **kwargs: float) -> None:
        s = self.get_val(x, y)

        if style:
            s.style = style

        for key, value in kwargs.items():
            if value < 0 or value > 1:
                raise Exception(
                    f"set_style expects values to be floats between 0 and 1, '{key}' was '{value}'"
                )

            match key:
                case "front_hue":
                    s.front_hue = value
                case "front_brightness":
                    s.front_brightness = value
                case "front_saturation":
                    s.front_saturation = value
                case "back_hue":
                    s.back_hue = value
                case "back_brightness":
                    s.back_brightness = value
                case "back_saturation":
                    s.back_saturation = value
                case _:
                    raise Exception(f"unknown key '{key}' in set_style")

    def get_front_rgb(self, x: int, y: int) -> tuple[int, int, int]:
        s = self.get_val(x, y)
        rgb = hsv_to_rgb(s.front_hue, s.front_saturation, s.front_brightness)
        ret = tuple(map(lambda c: round(c * 255), rgb))
        assert len(ret) == 3
        return ret

    def get_back_rgb(self, x: int, y: int) -> tuple[int, int, int]:
        s = self.get_val(x, y)
        rgb = hsv_to_rgb(s.back_hue, s.back_saturation, s.back_brightness)
        ret = tuple(map(lambda c: round(c * 255), rgb))
        assert len(ret) == 3
        return ret

    def __str__(self) -> str:
        ret = ""
        for y in range(self.height):
            for x in range(self.width):
                s = self.get_val(x, y)
                fr, fg, fb = self.get_front_rgb(x, y)
                br, bg, bb = self.get_back_rgb(x, y)
                ret += f"{Fore.rgb(fr, fg, fb)}{Back.rgb(br, bg, bb)}{s.val}{Style.reset}"
            ret += "\n"
        return ret

    @classmethod
    def blue_to_red_hue(cls, val: float) -> float:
        """Converts a floating point value to a point in a red-to-blue gradient,
        where high values are red and lower values are blue. Good for
        representing values in a range as a heat map for easy visualization of
        higher values.

        Args:
            val (float): The value to convert.

        Returns:
            float: The hue in the red-to-blue gradient.
        """
        # blue = 2/3
        # blue to red spectrum = 2/3 through 3/3
        # return value is a portion of the blue-to-red spectrum
        return (2 / 3) + ((1 / 3) * val)

    @classmethod
    def five_color_hue(cls, val: float) -> float:
        """Converts a value to a hue along a red-orange-yellow-green-blue
        spectrum. Higher values are red, lower values are blue. Good for
        visually differentiating a range of values.

        Args:
            val (float): The value to convert.

        Returns:
            float: The hue in the red-orange-yellow-green-blue gradient.
        """
        # red = 0
        # blue = 2/3
        # red to blue spectrum = 0 through 2/3
        # five colors = red, orange, yellow, green, blue
        # return value is a portion of the red-to-blue spectrum
        return (2 / 3) * (1 - val)

__array_finalize__(obj)

Source code in roc/location.py
219
220
221
def __array_finalize__(self, obj: npt.NDArray[Any] | None) -> None:
    if obj is None:
        return

__new__(grid)

Source code in roc/location.py
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
def __new__(cls, grid: IntGrid) -> DebugGrid:
    # obj = np.ndarray((grid.height, grid.width), dtype=object).view(DebugGrid)
    obj = np.array(
        [
            [
                GridStyle(
                    front_hue=0,
                    front_saturation=0,
                    front_brightness=1,
                    back_hue=0,
                    back_saturation=1,
                    back_brightness=0,
                    val=chr(grid[row, col]),
                    style="none",
                )
                for col in range(grid.width)
            ]
            for row in range(grid.height)
        ]
    ).view(DebugGrid)
    return obj

__str__()

Source code in roc/location.py
291
292
293
294
295
296
297
298
299
300
def __str__(self) -> str:
    ret = ""
    for y in range(self.height):
        for x in range(self.width):
            s = self.get_val(x, y)
            fr, fg, fb = self.get_front_rgb(x, y)
            br, bg, bb = self.get_back_rgb(x, y)
            ret += f"{Fore.rgb(fr, fg, fb)}{Back.rgb(br, bg, bb)}{s.val}{Style.reset}"
        ret += "\n"
    return ret

blue_to_red_hue(val) classmethod

Converts a floating point value to a point in a red-to-blue gradient, where high values are red and lower values are blue. Good for representing values in a range as a heat map for easy visualization of higher values.

Parameters:

Name Type Description Default
val float

The value to convert.

required

Returns:

Name Type Description
float float

The hue in the red-to-blue gradient.

Source code in roc/location.py
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
@classmethod
def blue_to_red_hue(cls, val: float) -> float:
    """Converts a floating point value to a point in a red-to-blue gradient,
    where high values are red and lower values are blue. Good for
    representing values in a range as a heat map for easy visualization of
    higher values.

    Args:
        val (float): The value to convert.

    Returns:
        float: The hue in the red-to-blue gradient.
    """
    # blue = 2/3
    # blue to red spectrum = 2/3 through 3/3
    # return value is a portion of the blue-to-red spectrum
    return (2 / 3) + ((1 / 3) * val)

five_color_hue(val) classmethod

Converts a value to a hue along a red-orange-yellow-green-blue spectrum. Higher values are red, lower values are blue. Good for visually differentiating a range of values.

Parameters:

Name Type Description Default
val float

The value to convert.

required

Returns:

Name Type Description
float float

The hue in the red-orange-yellow-green-blue gradient.

Source code in roc/location.py
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
@classmethod
def five_color_hue(cls, val: float) -> float:
    """Converts a value to a hue along a red-orange-yellow-green-blue
    spectrum. Higher values are red, lower values are blue. Good for
    visually differentiating a range of values.

    Args:
        val (float): The value to convert.

    Returns:
        float: The hue in the red-orange-yellow-green-blue gradient.
    """
    # red = 0
    # blue = 2/3
    # red to blue spectrum = 0 through 2/3
    # five colors = red, orange, yellow, green, blue
    # return value is a portion of the red-to-blue spectrum
    return (2 / 3) * (1 - val)

get_back_rgb(x, y)

Source code in roc/location.py
284
285
286
287
288
289
def get_back_rgb(self, x: int, y: int) -> tuple[int, int, int]:
    s = self.get_val(x, y)
    rgb = hsv_to_rgb(s.back_hue, s.back_saturation, s.back_brightness)
    ret = tuple(map(lambda c: round(c * 255), rgb))
    assert len(ret) == 3
    return ret

get_front_rgb(x, y)

Source code in roc/location.py
277
278
279
280
281
282
def get_front_rgb(self, x: int, y: int) -> tuple[int, int, int]:
    s = self.get_val(x, y)
    rgb = hsv_to_rgb(s.front_hue, s.front_saturation, s.front_brightness)
    ret = tuple(map(lambda c: round(c * 255), rgb))
    assert len(ret) == 3
    return ret

set_style(x, y, *, style=None, **kwargs)

Source code in roc/location.py
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
def set_style(self, x: int, y: int, *, style: str | None = None, **kwargs: float) -> None:
    s = self.get_val(x, y)

    if style:
        s.style = style

    for key, value in kwargs.items():
        if value < 0 or value > 1:
            raise Exception(
                f"set_style expects values to be floats between 0 and 1, '{key}' was '{value}'"
            )

        match key:
            case "front_hue":
                s.front_hue = value
            case "front_brightness":
                s.front_brightness = value
            case "front_saturation":
                s.front_saturation = value
            case "back_hue":
                s.back_hue = value
            case "back_brightness":
                s.back_brightness = value
            case "back_saturation":
                s.back_saturation = value
            case _:
                raise Exception(f"unknown key '{key}' in set_style")

Grid

Bases: NDArray[Any], Generic[GridType]

Source code in roc/location.py
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
class Grid(npt.NDArray[Any], Generic[GridType]):
    def __new__(cls, input_array: npt.ArrayLike) -> Self:
        obj = np.asarray(input_array).view(cls)
        assert obj.ndim == 2
        return obj

    # def __array_finalize__(self, obj: npt.NDArray[Any] | None) -> None:
    #     if obj is None:
    #         return

    def __iter__(self) -> Iterator[ValLocTuple[GridType]]:
        for y, x in np.ndindex(self.shape):
            yield cast(ValLocTuple[GridType], (x, y, self[y, x]))
        # yield from np.nditer(self)

    # def __init__(self, val_list: list[list[Any]] | np.ndarray) -> None:
    #     if not isinstance(val_list, np.ndarray):
    #         val_list = np.array(val_list)
    #     assert val_list.ndim == 2
    #     self.val_list = val_list

    def get_val(self, x: int, y: int) -> GridType:
        # XXX: not sure why I need to cast here, should this already be typed?
        return cast(GridType, self[y, x])

    def set_val(self, x: int, y: int, v: GridType) -> None:
        self[y, x] = v

    @property
    def width(self) -> int:
        # XXX: shape is a tuple of ints, not sure why this is being grumpy
        # https://numpy.org/doc/2.1/reference/generated/numpy.shape.html
        return self.shape[1]  # type: ignore

    @property
    def height(self) -> int:
        return self.shape[0]  # type: ignore

height property

width property

__iter__()

Source code in roc/location.py
122
123
124
def __iter__(self) -> Iterator[ValLocTuple[GridType]]:
    for y, x in np.ndindex(self.shape):
        yield cast(ValLocTuple[GridType], (x, y, self[y, x]))

__new__(input_array)

Source code in roc/location.py
113
114
115
116
def __new__(cls, input_array: npt.ArrayLike) -> Self:
    obj = np.asarray(input_array).view(cls)
    assert obj.ndim == 2
    return obj

get_val(x, y)

Source code in roc/location.py
133
134
135
def get_val(self, x: int, y: int) -> GridType:
    # XXX: not sure why I need to cast here, should this already be typed?
    return cast(GridType, self[y, x])

set_val(x, y, v)

Source code in roc/location.py
137
138
def set_val(self, x: int, y: int, v: GridType) -> None:
    self[y, x] = v

GridStyle dataclass

A stylized point on a text grid, where the text can be printed in any foreground or background color or style. Colors can be set using hue, saturation, and brightness (HSV) so that independent variables can control what color, how saturated the color is, and how bright the color is. This gives at least six debugging degrees of freedom for each point in the grid (in addition to value and style).

Source code in roc/location.py
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
@dataclass
class GridStyle:
    """A stylized point on a text grid, where the text can be printed in any
    foreground or background color or style. Colors can be set using hue,
    saturation, and brightness (HSV) so that independent variables can control
    what color, how saturated the color is, and how bright the color is. This
    gives at least six debugging degrees of freedom for each point in the grid
    (in addition to value and style).
    """

    front_hue: float
    front_saturation: float
    front_brightness: float
    back_hue: float
    back_saturation: float
    back_brightness: float
    style: str
    val: str

back_brightness instance-attribute

back_hue instance-attribute

back_saturation instance-attribute

front_brightness instance-attribute

front_hue instance-attribute

front_saturation instance-attribute

style instance-attribute

val instance-attribute

__init__(front_hue, front_saturation, front_brightness, back_hue, back_saturation, back_brightness, style, val)

IntGrid

Bases: Grid[int]

Source code in roc/location.py
151
152
153
154
155
156
157
158
class IntGrid(Grid[int]):
    def get_point(self, x: XLoc, y: YLoc) -> Point:
        return Point(x, y, self[y, x])

    def points(self) -> Iterator[Point]:
        """Iterate over all the points in the grid"""
        for x, y, v in self:
            yield Point(x, y, v)

get_point(x, y)

Source code in roc/location.py
152
153
def get_point(self, x: XLoc, y: YLoc) -> Point:
    return Point(x, y, self[y, x])

points()

Iterate over all the points in the grid

Source code in roc/location.py
155
156
157
158
def points(self) -> Iterator[Point]:
    """Iterate over all the points in the grid"""
    for x, y, v in self:
        yield Point(x, y, v)

Point

Represents a int value at a 2D location (x, y)

Source code in roc/location.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
class Point:
    """Represents a int value at a 2D location (x, y)"""

    def __init__(self, x: XLoc, y: YLoc, val: int) -> None:
        self.x = x
        self.y = y
        self.val = val

    def __hash__(self) -> int:
        return hash((self.x, self.y))

    def __repr__(self) -> str:
        return f"({self.x}, {self.y}): {self.val} '{chr(self.val)}'"

    def __eq__(self, p: Any) -> bool:
        if not isinstance(p, Point):
            return False
        return self.x == p.x and self.y == p.y and self.val == p.val

    @staticmethod
    def from_valloc(t: ValLocTuple[int]) -> Point:
        """Converts a value / location tuple (value, x, y) to a Point.

        Args:
            t (ValLocTuple[int]): The tuple to convert

        Returns:
            Point: The new point that was created
        """
        x, y, v = t
        return Point(x, y, v)

    @overload
    @staticmethod
    def isadjacent(*, x1: XLoc, y1: YLoc, x2: XLoc, y2: YLoc) -> bool: ...

    @overload
    @staticmethod
    def isadjacent(*, p1: Point, x2: XLoc, y2: YLoc) -> bool: ...

    @overload
    @staticmethod
    def isadjacent(*, p1: Point, p2: Point) -> bool: ...

    @staticmethod
    def isadjacent(
        # o1: int | Point, o2: int | Point, o3: int | None = None, o4: int | None = None
        *,
        x1: XLoc | None = None,
        y1: YLoc | None = None,
        x2: XLoc | None = None,
        y2: YLoc | None = None,
        p1: Point | None = None,
        p2: Point | None = None,
    ) -> bool:
        if isinstance(p1, Point):
            x1 = p1.x
            y1 = p1.y
        elif not isinstance(x1, int) or not isinstance(y1, int):
            raise TypeError("bad p1 arguments in isadjacent()")

        if isinstance(p2, Point):
            x2 = p2.x
            y2 = p2.y
        elif not isinstance(x2, int) or not isinstance(y2, int):
            raise TypeError("bad p2 arguments in isadjacent()")

        dx = abs(x1 - x2)
        dy = abs(y1 - y2)
        if dx == 0 and dy == 0:
            return False

        return dx <= 1 and dy <= 1

val = val instance-attribute

x = x instance-attribute

y = y instance-attribute

__eq__(p)

Source code in roc/location.py
29
30
31
32
def __eq__(self, p: Any) -> bool:
    if not isinstance(p, Point):
        return False
    return self.x == p.x and self.y == p.y and self.val == p.val

__hash__()

Source code in roc/location.py
23
24
def __hash__(self) -> int:
    return hash((self.x, self.y))

__init__(x, y, val)

Source code in roc/location.py
18
19
20
21
def __init__(self, x: XLoc, y: YLoc, val: int) -> None:
    self.x = x
    self.y = y
    self.val = val

__repr__()

Source code in roc/location.py
26
27
def __repr__(self) -> str:
    return f"({self.x}, {self.y}): {self.val} '{chr(self.val)}'"

from_valloc(t) staticmethod

Converts a value / location tuple (value, x, y) to a Point.

Parameters:

Name Type Description Default
t ValLocTuple[int]

The tuple to convert

required

Returns:

Name Type Description
Point Point

The new point that was created

Source code in roc/location.py
34
35
36
37
38
39
40
41
42
43
44
45
@staticmethod
def from_valloc(t: ValLocTuple[int]) -> Point:
    """Converts a value / location tuple (value, x, y) to a Point.

    Args:
        t (ValLocTuple[int]): The tuple to convert

    Returns:
        Point: The new point that was created
    """
    x, y, v = t
    return Point(x, y, v)

isadjacent(*, x1=None, y1=None, x2=None, y2=None, p1=None, p2=None) staticmethod

isadjacent(
    *, x1: XLoc, y1: YLoc, x2: XLoc, y2: YLoc
) -> bool
isadjacent(*, p1: Point, x2: XLoc, y2: YLoc) -> bool
isadjacent(*, p1: Point, p2: Point) -> bool
Source code in roc/location.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
@staticmethod
def isadjacent(
    # o1: int | Point, o2: int | Point, o3: int | None = None, o4: int | None = None
    *,
    x1: XLoc | None = None,
    y1: YLoc | None = None,
    x2: XLoc | None = None,
    y2: YLoc | None = None,
    p1: Point | None = None,
    p2: Point | None = None,
) -> bool:
    if isinstance(p1, Point):
        x1 = p1.x
        y1 = p1.y
    elif not isinstance(x1, int) or not isinstance(y1, int):
        raise TypeError("bad p1 arguments in isadjacent()")

    if isinstance(p2, Point):
        x2 = p2.x
        y2 = p2.y
    elif not isinstance(x2, int) or not isinstance(y2, int):
        raise TypeError("bad p2 arguments in isadjacent()")

    dx = abs(x1 - x2)
    dy = abs(y1 - y2)
    if dx == 0 and dy == 0:
        return False

    return dx <= 1 and dy <= 1

PointCollection

A collection of abitrary points

Source code in roc/location.py
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
class PointCollection:
    """A collection of abitrary points"""

    def __init__(self, point_list: PointList) -> None:
        self._point_hash: dict[int, Point] = {}
        for p in point_list:
            self.add(p)

    def add(self, p: Point) -> None:
        """Adds a new point to the collection"""
        hash_val = self.do_hash(p)
        self._point_hash[hash_val] = p

    def contains(self, p: Point) -> bool:
        """Verifies if a point is already in the collection or not"""
        hash_val = self.do_hash(p)
        return hash_val in self._point_hash

    def do_hash(self, p: Point) -> int:
        """Returns the hash value of a point. Mostly for internal use."""
        return hash((p.x, p.y))

    @property
    def size(self) -> int:
        return len(self._point_hash)

    @property
    def points(self) -> PointList:
        return list(self._point_hash.values())

points property

size property

__init__(point_list)

Source code in roc/location.py
343
344
345
346
def __init__(self, point_list: PointList) -> None:
    self._point_hash: dict[int, Point] = {}
    for p in point_list:
        self.add(p)

add(p)

Adds a new point to the collection

Source code in roc/location.py
348
349
350
351
def add(self, p: Point) -> None:
    """Adds a new point to the collection"""
    hash_val = self.do_hash(p)
    self._point_hash[hash_val] = p

contains(p)

Verifies if a point is already in the collection or not

Source code in roc/location.py
353
354
355
356
def contains(self, p: Point) -> bool:
    """Verifies if a point is already in the collection or not"""
    hash_val = self.do_hash(p)
    return hash_val in self._point_hash

do_hash(p)

Returns the hash value of a point. Mostly for internal use.

Source code in roc/location.py
358
359
360
def do_hash(self, p: Point) -> int:
    """Returns the hash value of a point. Mostly for internal use."""
    return hash((p.x, p.y))

TextGrid

Bases: IntGrid

Source code in roc/location.py
161
162
163
164
165
166
167
168
169
170
171
172
173
class TextGrid(IntGrid):
    def __str__(self) -> str:
        ret = ""
        last_y = 0
        for x, y, v in self:
            if y != last_y:
                ret += "\n"
                last_y = y

            ret += chr(v)

        ret += "\n"
        return ret

__str__()

Source code in roc/location.py
162
163
164
165
166
167
168
169
170
171
172
173
def __str__(self) -> str:
    ret = ""
    last_y = 0
    for x, y, v in self:
        if y != last_y:
            ret += "\n"
            last_y = y

        ret += chr(v)

    ret += "\n"
    return ret

TypedPointCollection

Bases: PointCollection

A collection of points that all have the same type

Source code in roc/location.py
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
class TypedPointCollection(PointCollection):
    """A collection of points that all have the same type"""

    def __init__(self, type: int, point_list: PointList) -> None:
        self.type = type
        super().__init__(point_list)

    def __repr__(self) -> str:
        return f"{len(self._point_hash)} Points: {self.type} ({chr(self.type)})"

    def do_hash(self, p: Point) -> int:
        return hash(p)

    def add(self, p: Point) -> None:
        """Add a new point to the collection and enforce that it is the same
        type as the collection
        """
        if p.val != self.type:
            raise TypeError(
                f"Trying to add '{p.val}' to TypedPointCollection with type '{self.type}"
            )

        super().add(p)

type = type instance-attribute

__init__(type, point_list)

Source code in roc/location.py
374
375
376
def __init__(self, type: int, point_list: PointList) -> None:
    self.type = type
    super().__init__(point_list)

__repr__()

Source code in roc/location.py
378
379
def __repr__(self) -> str:
    return f"{len(self._point_hash)} Points: {self.type} ({chr(self.type)})"

add(p)

Add a new point to the collection and enforce that it is the same type as the collection

Source code in roc/location.py
384
385
386
387
388
389
390
391
392
393
def add(self, p: Point) -> None:
    """Add a new point to the collection and enforce that it is the same
    type as the collection
    """
    if p.val != self.type:
        raise TypeError(
            f"Trying to add '{p.val}' to TypedPointCollection with type '{self.type}"
        )

    super().add(p)

do_hash(p)

Source code in roc/location.py
381
382
def do_hash(self, p: Point) -> int:
    return hash(p)