-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLightPattern.py
More file actions
66 lines (48 loc) · 1.99 KB
/
LightPattern.py
File metadata and controls
66 lines (48 loc) · 1.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
from dataclasses import dataclass, field
from typing import Tuple, Union, List, Iterator, Optional
RGB = Tuple[int, int, int]
def _validate_rgb(value: Union[RGB, tuple, list]) -> RGB:
if not (isinstance(value, (tuple, list)) and len(value) == 3 and all(isinstance(v, int) and 0 <= v <= 255 for v in value)):
raise TypeError("color must be an RGB tuple (r, g, b) with 0-255 ints")
return tuple(value)
@dataclass
class Light:
color: RGB = field(default_factory=lambda: (255, 255, 255), metadata={"validate": _validate_rgb})
count: int = 1
def __post_init__(self):
if self.count < 0:
raise ValueError("count must be non-negative")
class LightPattern:
def __init__(self, lights: Optional[List[Light]] = None):
self._lights: List[Light] = []
if lights:
for l in lights:
self.add_light(l.color, l.count)
def add_light(self, color: RGB, count: int = 1) -> "LightPattern":
self._lights.append(Light(color=color, count=count))
return self
def as_list(self) -> List[Light]:
return list(self._lights)
def clear(self) -> None:
self._lights.clear()
def display(self) -> None:
for light in self._lights:
print(f"{light.color}({light.count})")
def __iter__(self) -> Iterator[Light]:
return iter(self._lights)
def __len__(self) -> int:
return len(self._lights)
def __repr__(self) -> str:
def _valid_rgb(c):
return (
isinstance(c, (tuple, list))
and len(c) == 3
and all(isinstance(v, int) and 0 <= v <= 255 for v in c)
)
for l in self._lights:
if not _valid_rgb(l.color):
raise ValueError("color must be an RGB tuple (r, g, b) with 0-255 ints")
return f"LightPattern({self._lights!r})"
# expose Light class as attribute for compatibility with code expecting
# `LightPattern.Light` construction
LightPattern.Light = Light