13
13
14
14
* Author(s): PaintYourDragon
15
15
"""
16
-
17
- # imports
16
+ from __future__ import annotations
18
17
19
18
__version__ = "0.0.0+auto.0"
20
19
__repo__ = "https://github.com/Adafruit/Adafruit_CircuitPython_FancyLED.git"
21
20
21
+ # imports
22
22
from math import floor
23
23
24
+ try :
25
+ from typing import Tuple , Union , Optional , List , Any
26
+ from circuitpython_typing .led import FillBasedColorUnion
27
+ except ImportError :
28
+ pass
29
+
24
30
25
31
# FancyLED provides color- and palette-related utilities for LED projects,
26
32
# offering a buttery smooth look instead of the usual 8-bit-like "blip blip"
@@ -46,16 +52,16 @@ class CRGB:
46
52
c = CRGB(CHSV(0.0, 1.0, 1.0))
47
53
"""
48
54
49
- def __init__ (self , red , green = 0.0 , blue = 0.0 ):
55
+ def __init__ (self , red : CHSV , green : float = 0.0 , blue : float = 0.0 ) -> None :
50
56
# pylint: disable=too-many-branches
51
57
if isinstance (red , CHSV ):
52
58
# If first/only argument is a CHSV type, perform HSV to RGB
53
59
# conversion.
54
- hsv = red # 'red' is CHSV, this is just more readable
55
- hue = hsv .hue * 6.0 # Hue circle = 0.0 to 6.0
56
- sxt = floor (hue ) # Sextant index is next-lower integer of hue
57
- frac = hue - sxt # Fraction-within-sextant is 0.0 to <1.0
58
- sxt = int (sxt ) % 6 # mod6 the sextant so it's always 0 to 5
60
+ hsv : CHSV = red # 'red' is CHSV, this is just more readable
61
+ hue : float = hsv .hue * 6.0 # Hue circle = 0.0 to 6.0
62
+ sxt : int = floor (hue ) # Sextant index is next-lower integer of hue
63
+ frac : float = hue - sxt # Fraction-within-sextant is 0.0 to <1.0
64
+ sxt : int = int (sxt ) % 6 # mod6 the sextant so it's always 0 to 5
59
65
60
66
if sxt == 0 : # Red to <yellow
61
67
r , g , b = 1.0 , frac , 0.0
@@ -70,7 +76,7 @@ def __init__(self, red, green=0.0, blue=0.0):
70
76
else : # Magenta to <red
71
77
r , g , b = 1.0 , 0.0 , 1.0 - frac
72
78
73
- invsat = 1.0 - hsv .saturation # Inverse-of-saturation
79
+ invsat : float = 1.0 - hsv .saturation # Inverse-of-saturation
74
80
75
81
self .red = ((r * hsv .saturation ) + invsat ) * hsv .value
76
82
self .green = ((g * hsv .saturation ) + invsat ) * hsv .value
@@ -81,17 +87,17 @@ def __init__(self, red, green=0.0, blue=0.0):
81
87
self .green = clamp_norm (green )
82
88
self .blue = clamp_norm (blue )
83
89
84
- def __repr__ (self ): # pylint: disable=invalid-repr-returned
90
+ def __repr__ (self ) -> Tuple [ int , int , int ] : # pylint: disable=invalid-repr-returned
85
91
return (self .red , self .green , self .blue )
86
92
87
- def __str__ (self ):
93
+ def __str__ (self ) -> str :
88
94
return "(%s, %s, %s)" % (self .red , self .green , self .blue )
89
95
90
- def __len__ (self ):
96
+ def __len__ (self ) -> int :
91
97
"""Retrieve total number of color-parts available."""
92
98
return 3
93
99
94
- def __getitem__ (self , key ) :
100
+ def __getitem__ (self , key : int ) -> float :
95
101
"""Retrieve red, green or blue value as iterable."""
96
102
if key == 0 :
97
103
return self .red
@@ -101,7 +107,7 @@ def __getitem__(self, key):
101
107
return self .blue
102
108
raise IndexError
103
109
104
- def pack (self , white = None ):
110
+ def pack (self , white : Optional [ float ] = None ) -> FillBasedColorUnion :
105
111
"""'Pack' a `CRGB` color into a 24-bit RGB integer, OR, optionally
106
112
assign a white element for RGBW NeoPixels and return as a 4-tuple,
107
113
either of which can be passed to the NeoPixel setter.
@@ -181,25 +187,27 @@ class CHSV:
181
187
"""
182
188
183
189
# pylint: disable=invalid-name
184
- def __init__ (self , h , s = 1.0 , v = 1.0 ):
190
+ def __init__ (self , h : float , s : float = 1.0 , v : float = 1.0 ) -> None :
185
191
if isinstance (h , float ):
186
- self .hue = h # Don't clamp! Hue can wrap around forever.
192
+ self .hue : float = h # Don't clamp! Hue can wrap around forever.
187
193
else :
188
- self .hue = float (h ) / 256.0
189
- self .saturation = clamp_norm (s )
190
- self .value = clamp_norm (v )
194
+ self .hue : float = float (h ) / 256.0
195
+ self .saturation : float = clamp_norm (s )
196
+ self .value : float = clamp_norm (v )
191
197
192
- def __repr__ (self ): # pylint: disable=invalid-repr-returned
198
+ def __repr__ ( # pylint: disable=invalid-repr-returned
199
+ self ,
200
+ ) -> Tuple [float , float , float ]:
193
201
return (self .hue , self .saturation , self .value )
194
202
195
- def __str__ (self ):
203
+ def __str__ (self ) -> str :
196
204
return "(%s, %s, %s)" % (self .hue , self .saturation , self .value )
197
205
198
- def __len__ (self ):
206
+ def __len__ (self ) -> int :
199
207
"""Retrieve total number of 'color-parts' available."""
200
208
return 3
201
209
202
- def __getitem__ (self , key ) :
210
+ def __getitem__ (self , key : int ) -> float :
203
211
"""Retrieve hue, saturation or value as iterable."""
204
212
if key == 0 :
205
213
return self .hue
@@ -209,7 +217,7 @@ def __getitem__(self, key):
209
217
return self .value
210
218
raise IndexError
211
219
212
- def pack (self , white = None ):
220
+ def pack (self , white : Optional [ float ] = None ) -> FillBasedColorUnion :
213
221
"""'Pack' a `CHSV` color into a 24-bit RGB integer, OR, optionally
214
222
assign a white element for RGBW NeoPixels and return as a 4-tuple,
215
223
either of which can be passed to the NeoPixel setter.
@@ -228,12 +236,16 @@ def pack(self, white=None):
228
236
return CRGB (self ).pack (white )
229
237
230
238
231
- def clamp (val , lower , upper ):
239
+ def clamp (
240
+ val : Union [int , float ], lower : Union [int , float ], upper : Union [int , float ]
241
+ ) -> Union [int , float ]:
232
242
"""Constrain value within a numeric range (inclusive)."""
233
243
return max (lower , min (val , upper ))
234
244
235
245
236
- def normalize (val , inplace = False ):
246
+ def normalize (
247
+ val : int , inplace : Optional [bool ] = False
248
+ ) -> Union [None , float , List [float ]]:
237
249
"""Convert 8-bit (0 to 255) value to normalized (0.0 to 1.0) value.
238
250
239
251
Accepts integer, 0 to 255 range (input is clamped) or a list or tuple
@@ -259,7 +271,7 @@ def normalize(val, inplace=False):
259
271
return [normalize (n ) for n in val ]
260
272
261
273
262
- def clamp_norm (val ) :
274
+ def clamp_norm (val : Union [ float , int ]) -> Union [ float , int ] :
263
275
"""Clamp or normalize a value as appropriate to its type. If a float is
264
276
received, the return value is the input clamped to a 0.0 to 1.0 range.
265
277
If an integer is received, a range of 0-255 is scaled to a float value
@@ -270,7 +282,9 @@ def clamp_norm(val):
270
282
return normalize (val )
271
283
272
284
273
- def denormalize (val , inplace = False ):
285
+ def denormalize (
286
+ val : Union [float , List [float ], Tuple [float ]], inplace : bool = False
287
+ ) -> Union [int , List [int ]]:
274
288
"""Convert normalized (0.0 to 1.0) value to 8-bit (0 to 255) value
275
289
276
290
Accepts float, 0.0 to 1.0 range or a list or tuple of floats. In
@@ -300,7 +314,7 @@ def denormalize(val, inplace=False):
300
314
return [denormalize (n ) for n in val ]
301
315
302
316
303
- def unpack (val ) :
317
+ def unpack (val : int ) -> CRGB :
304
318
"""'Unpack' a 24-bit color into a `CRGB` instance.
305
319
306
320
:param int val: 24-bit integer a la ``0x00RRGGBB``.
@@ -318,7 +332,9 @@ def unpack(val):
318
332
) # Blue
319
333
320
334
321
- def mix (color1 , color2 , weight2 = 0.5 ):
335
+ def mix (
336
+ color1 : Union [CRGB , CHSV ], color2 : Union [CRGB , CHSV ], weight2 : float = 0.5
337
+ ) -> CRGB :
322
338
"""Blend between two colors using given ratio. Accepts two colors (each
323
339
may be `CRGB`, `CHSV` or packed integer), and weighting (0.0 to 1.0)
324
340
of second color.
@@ -327,7 +343,7 @@ def mix(color1, color2, weight2=0.5):
327
343
"""
328
344
329
345
clamp (weight2 , 0.0 , 1.0 )
330
- weight1 = 1.0 - weight2
346
+ weight1 : float = 1.0 - weight2
331
347
332
348
if isinstance (color1 , CHSV ):
333
349
if isinstance (color2 , CHSV ):
@@ -369,7 +385,12 @@ def mix(color1, color2, weight2=0.5):
369
385
GFACTOR = 2.7 # Default gamma-correction factor for function below
370
386
371
387
372
- def gamma_adjust (val , gamma_value = None , brightness = 1.0 , inplace = False ):
388
+ def gamma_adjust (
389
+ val : Any ,
390
+ gamma_value : Any = None ,
391
+ brightness : Optional [Union [float , Tuple [int , int , int ]]] = 1.0 ,
392
+ inplace : Optional [bool ] = False ,
393
+ ) -> Union [float , CRGB , List [Union [float , CRGB ]]]:
373
394
"""Provides gamma adjustment for single values, `CRGB` and `CHSV` types
374
395
and lists of any of these.
375
396
@@ -506,7 +527,9 @@ def gamma_adjust(val, gamma_value=None, brightness=1.0, inplace=False):
506
527
)
507
528
508
529
509
- def palette_lookup (palette , position ):
530
+ def palette_lookup (
531
+ palette : Union [List [CRGB ], List [CHSV ], List [int ]], position : float
532
+ ) -> Union [CRGB , CHSV ]:
510
533
"""Fetch color from color palette, with interpolation.
511
534
512
535
:param palette: color palette (list of CRGB, CHSV and/or packed integers)
@@ -528,7 +551,13 @@ def palette_lookup(palette, position):
528
551
return mix (color1 , color2 , weight2 )
529
552
530
553
531
- def expand_gradient (gradient , length ):
554
+ def expand_gradient (
555
+ gradient : Union [
556
+ List [List [float , Union [int , CRGB , CHSV ]]],
557
+ Tuple [Tuple [float , Union [int , CRGB , CHSV ]]],
558
+ ],
559
+ length : float ,
560
+ ) -> List [CRGB ]:
532
561
"""Convert gradient palette into standard equal-interval palette.
533
562
534
563
:param sequence gradient: List or tuple of of 2-element lists/tuples
0 commit comments