PyDMXControl._Colors   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 216
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 10
eloc 57
dl 0
loc 216
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A Colors.mix() 0 33 2
A Colors.to_print() 0 22 1
A Colors.add() 0 36 2
A Colors.to_dict() 0 22 1
A Colors.to_hex() 0 24 2
A Colors.to_tuples() 0 22 1
A Colors.clamp() 0 23 1
1
"""
2
 *  PyDMXControl: A Python 3 module to control DMX using OpenDMX or uDMX.
3
 *                Featuring fixture profiles, built-in effects and a web control panel.
4
 *  <https://github.com/MattIPv4/PyDMXControl/>
5
 *  Copyright (C) 2018 Matt Cowley (MattIPv4) ([email protected])
6
"""
7
8
import itertools
9
from enum import Enum
10
from typing import List, Dict, Tuple, Union
11
12
13
class Colors(list, Enum):
14
15
    @staticmethod
16
    def clamp(val: Union[int, float], lo: int = 0, hi: int = 255) -> Union[int, float]:
17
        """
18
        Clamp a value to ensure it fits in a range (default [0..255])
19
20
        Parameters
21
        ----------
22
        val: Value to clamp.
23
        lo: Minimum value.
24
        hi: Maximum value.
25
26
        Returns
27
        -------
28
        Union[int, float]
29
            Clamped value. [lo..hi]
30
        
31
        Examples
32
        --------
33
34
        >>> Colors.clamp(2323.52)
35
        255
36
        """
37
        return min(hi, max(lo, val))
38
39
    @staticmethod
40
    def mix(color1: List[int], color2: List[int], percent: float = 0.5) -> List[int]:
41
        """Mix two colors, with an optional percentage.
42
43
        Mixes `percent` of color1 with 1-`percent` of color2.
44
45
        Parameters
46
        ----------
47
        color1: The first color.
48
        color2: The second color.
49
        percent: Ratio in which two colors are to be mixed (0..1).
50
51
        Returns
52
        -------
53
        List[int]
54
            New color after mixing.
55
        
56
        Examples
57
        --------
58
59
        >>> Colors.mix([0,128,0], [128,0,128], 0.5)    
60
        [64, 64, 64]
61
        """
62
        percent = Colors.clamp(percent, 0, 1)
63
64
        result = []
65
        for val1, val2 in itertools.zip_longest(color1, color2, fillvalue=0):
66
            val1 *= percent
67
            val2 *= 1 - percent
68
            res = Colors.clamp(val1 + val2)
69
            result.append(int(res))
70
71
        return result
72
73
    @staticmethod
74
    def add(color1: List[int], color2: List[int], percent1: float = 1, percent2: float = 1) -> List[int]:
75
        """Add two colors.
76
77
        Adds `percent1` of color1 with `percent2` of color2.
78
79
        Parameters
80
        ----------
81
        color1: The first color.
82
        color2: The second color.
83
        percent1: Percentage of brightness of color 1 (0..1).
84
        percent2: Percentage of brightness of color 2 (0..1).
85
86
        Returns
87
        -------
88
        List[int]
89
            New color after mixing.
90
        
91
        Examples
92
        --------
93
94
        >>> Colors.add([0,128,0], [128,0,128], 1, 0.75)
95
        [96, 128, 96]
96
        """
97
98
        percent1 = Colors.clamp(percent1, 0, 1)
99
        percent2 = Colors.clamp(percent2, 0, 1)
100
101
        result = []
102
        for val1, val2 in itertools.zip_longest(color1, color2, fillvalue=0):
103
            val1 *= percent1
104
            val2 *= percent2
105
            res = Colors.clamp(val1 + val2)
106
            result.append(int(res))
107
108
        return result
109
110
    @staticmethod
111
    def to_dict(colors: List[int]) -> Dict[str, int]:
112
        """Convert a color from list form to a dict.
113
        
114
        Assumes RGBWA.
115
        
116
        Parameters
117
        ----------
118
        colors: Color to convert to a dictionary.
119
120
        Returns
121
        -------
122
        Dict[str, int]
123
            Color as a dictionary.
124
125
        Examples
126
        --------
127
128
        >>> Colors.to_dict([1,2,3,4,5]) 
129
        {'R': 1, 'G': 2, 'B': 3, 'W': 4, 'A': 5}
130
        """
131
        return dict(zip('RGBWA', colors))
132
133
    @staticmethod
134
    def to_tuples(colors: List[int]) -> List[Tuple[str, int]]:
135
        """Convert a color from a list to a list of tuples.
136
        
137
        Assumes RGBWA.
138
        
139
        Parameters
140
        ----------
141
        colors: Color to convert to tuples.
142
143
        Returns
144
        -------
145
        List[Tuple[str, int]]
146
            Color as a list of tuples.
147
148
        Examples
149
        --------
150
151
        >>> Colors.to_tuples([1,2,3,4,5]) 
152
        [('R', 1), ('G', 2), ('B', 3), ('W', 4), ('A', 5)]
153
        """
154
        return list(zip('RGBWA', colors))
155
156
    @staticmethod
157
    def to_hex(colors: List[int]) -> str:
158
        """Convert a color from list to hex form.
159
160
        Parameters
161
        ----------
162
        colors: Color to convert to tuples.
163
164
        Returns
165
        -------
166
        str
167
            Color as a hex string.
168
169
        Examples
170
        --------
171
172
        >>> Colors.to_hex([95, 93, 12])
173
        '#5f5d0c'
174
        """
175
176
        result = "#"
177
        for color in colors:
178
            result += "{:02x}".format(Colors.clamp(color))
179
        return result
180
181
    @staticmethod
182
    def to_print(colors: List[int], separator: str = ", ") -> str:
183
        """Convert a color from list form to a printable string.
184
185
        Parameters
186
        ----------
187
        colors: Color to convert to printable form.
188
        separator: Separator to use.
189
190
        Returns
191
        -------
192
        str
193
            Color as a printable string.
194
195
        Examples
196
        --------
197
198
        >>> Colors.to_print([95, 93, 12, 18, 128]) 
199
        '95, 93, 12, 18, 128'
200
        """
201
202
        return separator.join([str(f) for f in colors])
203
204
    Black = [000, 000, 000, 000]
205
    White = [255, 255, 255, 255]
206
    Warm = [255, 170, 85, 85]
207
    Red = [255, 000, 000, 000]
208
    Amber = [255, 127, 000, 000]
209
    Yellow = [255, 255, 000, 000]
210
    Green = [000, 255, 000, 000]
211
    Cyan = [000, 255, 255, 000]
212
    Blue = [000, 000, 255, 000]
213
    Pink = [255, 105, 180, 000]
214
    UV = [75, 000, 130, 000]
215
    Magenta = [255, 000, 255, 000]
216