1313
1414* Author(s): PaintYourDragon
1515"""
16-
17- # imports
16+ from __future__ import annotations
1817
1918__version__ = "0.0.0+auto.0"
2019__repo__ = "https://github.com/Adafruit/Adafruit_CircuitPython_FancyLED.git"
2120
21+ # imports
2222from math import floor
2323
24+ try :
25+ from typing import Tuple , Union , Optional , List , Any
26+ from circuitpython_typing .led import FillBasedColorUnion
27+ except ImportError :
28+ pass
29+
2430
2531# FancyLED provides color- and palette-related utilities for LED projects,
2632# offering a buttery smooth look instead of the usual 8-bit-like "blip blip"
@@ -46,16 +52,16 @@ class CRGB:
4652 c = CRGB(CHSV(0.0, 1.0, 1.0))
4753 """
4854
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 :
5056 # pylint: disable=too-many-branches
5157 if isinstance (red , CHSV ):
5258 # If first/only argument is a CHSV type, perform HSV to RGB
5359 # 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
5965
6066 if sxt == 0 : # Red to <yellow
6167 r , g , b = 1.0 , frac , 0.0
@@ -70,7 +76,7 @@ def __init__(self, red, green=0.0, blue=0.0):
7076 else : # Magenta to <red
7177 r , g , b = 1.0 , 0.0 , 1.0 - frac
7278
73- invsat = 1.0 - hsv .saturation # Inverse-of-saturation
79+ invsat : float = 1.0 - hsv .saturation # Inverse-of-saturation
7480
7581 self .red = ((r * hsv .saturation ) + invsat ) * hsv .value
7682 self .green = ((g * hsv .saturation ) + invsat ) * hsv .value
@@ -81,17 +87,17 @@ def __init__(self, red, green=0.0, blue=0.0):
8187 self .green = clamp_norm (green )
8288 self .blue = clamp_norm (blue )
8389
84- def __repr__ (self ): # pylint: disable=invalid-repr-returned
90+ def __repr__ (self ) -> Tuple [ int , int , int ] : # pylint: disable=invalid-repr-returned
8591 return (self .red , self .green , self .blue )
8692
87- def __str__ (self ):
93+ def __str__ (self ) -> str :
8894 return "(%s, %s, %s)" % (self .red , self .green , self .blue )
8995
90- def __len__ (self ):
96+ def __len__ (self ) -> int :
9197 """Retrieve total number of color-parts available."""
9298 return 3
9399
94- def __getitem__ (self , key ) :
100+ def __getitem__ (self , key : int ) -> float :
95101 """Retrieve red, green or blue value as iterable."""
96102 if key == 0 :
97103 return self .red
@@ -101,7 +107,7 @@ def __getitem__(self, key):
101107 return self .blue
102108 raise IndexError
103109
104- def pack (self , white = None ):
110+ def pack (self , white : Optional [ float ] = None ) -> FillBasedColorUnion :
105111 """'Pack' a `CRGB` color into a 24-bit RGB integer, OR, optionally
106112 assign a white element for RGBW NeoPixels and return as a 4-tuple,
107113 either of which can be passed to the NeoPixel setter.
@@ -181,25 +187,27 @@ class CHSV:
181187 """
182188
183189 # 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 :
185191 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.
187193 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 )
191197
192- def __repr__ (self ): # pylint: disable=invalid-repr-returned
198+ def __repr__ ( # pylint: disable=invalid-repr-returned
199+ self ,
200+ ) -> Tuple [float , float , float ]:
193201 return (self .hue , self .saturation , self .value )
194202
195- def __str__ (self ):
203+ def __str__ (self ) -> str :
196204 return "(%s, %s, %s)" % (self .hue , self .saturation , self .value )
197205
198- def __len__ (self ):
206+ def __len__ (self ) -> int :
199207 """Retrieve total number of 'color-parts' available."""
200208 return 3
201209
202- def __getitem__ (self , key ) :
210+ def __getitem__ (self , key : int ) -> float :
203211 """Retrieve hue, saturation or value as iterable."""
204212 if key == 0 :
205213 return self .hue
@@ -209,7 +217,7 @@ def __getitem__(self, key):
209217 return self .value
210218 raise IndexError
211219
212- def pack (self , white = None ):
220+ def pack (self , white : Optional [ float ] = None ) -> FillBasedColorUnion :
213221 """'Pack' a `CHSV` color into a 24-bit RGB integer, OR, optionally
214222 assign a white element for RGBW NeoPixels and return as a 4-tuple,
215223 either of which can be passed to the NeoPixel setter.
@@ -228,12 +236,16 @@ def pack(self, white=None):
228236 return CRGB (self ).pack (white )
229237
230238
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 ]:
232242 """Constrain value within a numeric range (inclusive)."""
233243 return max (lower , min (val , upper ))
234244
235245
236- def normalize (val , inplace = False ):
246+ def normalize (
247+ val : int , inplace : Optional [bool ] = False
248+ ) -> Union [None , float , List [float ]]:
237249 """Convert 8-bit (0 to 255) value to normalized (0.0 to 1.0) value.
238250
239251 Accepts integer, 0 to 255 range (input is clamped) or a list or tuple
@@ -259,7 +271,7 @@ def normalize(val, inplace=False):
259271 return [normalize (n ) for n in val ]
260272
261273
262- def clamp_norm (val ) :
274+ def clamp_norm (val : Union [ float , int ]) -> Union [ float , int ] :
263275 """Clamp or normalize a value as appropriate to its type. If a float is
264276 received, the return value is the input clamped to a 0.0 to 1.0 range.
265277 If an integer is received, a range of 0-255 is scaled to a float value
@@ -270,7 +282,9 @@ def clamp_norm(val):
270282 return normalize (val )
271283
272284
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 ]]:
274288 """Convert normalized (0.0 to 1.0) value to 8-bit (0 to 255) value
275289
276290 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):
300314 return [denormalize (n ) for n in val ]
301315
302316
303- def unpack (val ) :
317+ def unpack (val : int ) -> CRGB :
304318 """'Unpack' a 24-bit color into a `CRGB` instance.
305319
306320 :param int val: 24-bit integer a la ``0x00RRGGBB``.
@@ -318,7 +332,9 @@ def unpack(val):
318332 ) # Blue
319333
320334
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 :
322338 """Blend between two colors using given ratio. Accepts two colors (each
323339 may be `CRGB`, `CHSV` or packed integer), and weighting (0.0 to 1.0)
324340 of second color.
@@ -327,7 +343,7 @@ def mix(color1, color2, weight2=0.5):
327343 """
328344
329345 clamp (weight2 , 0.0 , 1.0 )
330- weight1 = 1.0 - weight2
346+ weight1 : float = 1.0 - weight2
331347
332348 if isinstance (color1 , CHSV ):
333349 if isinstance (color2 , CHSV ):
@@ -369,7 +385,12 @@ def mix(color1, color2, weight2=0.5):
369385GFACTOR = 2.7 # Default gamma-correction factor for function below
370386
371387
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 ]]]:
373394 """Provides gamma adjustment for single values, `CRGB` and `CHSV` types
374395 and lists of any of these.
375396
@@ -506,7 +527,9 @@ def gamma_adjust(val, gamma_value=None, brightness=1.0, inplace=False):
506527 )
507528
508529
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 ]:
510533 """Fetch color from color palette, with interpolation.
511534
512535 :param palette: color palette (list of CRGB, CHSV and/or packed integers)
@@ -528,7 +551,13 @@ def palette_lookup(palette, position):
528551 return mix (color1 , color2 , weight2 )
529552
530553
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 ]:
532561 """Convert gradient palette into standard equal-interval palette.
533562
534563 :param sequence gradient: List or tuple of of 2-element lists/tuples
0 commit comments