Repository: ManiacalLabs/BiblioPixel
Pull request #283 (2017-07-09 13:59:39)

Improvements to color.


Patch:
diff --git a/bibliopixel/colors/__init__.py b/bibliopixel/colors/__init__.py
index 75b01fd..893ebf9 100644
--- a/bibliopixel/colors/__init__.py
+++ b/bibliopixel/colors/__init__.py
@@ -46,11 +46,15 @@ More details here: https://github.com/FastLED/FastLED/wiki/FastLED-HSV-Colors
 """
 
 from . arithmetic import color_blend, color_scale
-from . hue import hsv2rgb_spectrum, hsv2rgb_rainbow, hsv2rgb_360
-from . hue import hsv2rgb, hue2rgb, hex2rgb, hue_gradient, hue2rgb_360
-from . hue import hue_helper, hue_helper360
+from . conversions import hsv2rgb_spectrum, hsv2rgb_rainbow, hsv2rgb_360
+from . conversions import hsv2rgb, hue2rgb, hue_gradient, hue2rgb_360
+from . conversions import hue_helper, hue_helper360
 from . wheel import wheel_color, wheel_helper
 from . names import COLORS
 
-# Legacy color names.
+# DEPRECATED methods and module name
+hex2rgb = COLORS.__getitem__
+from . import conversions as hue
+
+# Legacy color names.  DEPRECATED
 from . classic import *  # noqa: F403
diff --git a/bibliopixel/colors/hue.py b/bibliopixel/colors/conversions.py
similarity index 95%
rename from bibliopixel/colors/hue.py
rename to bibliopixel/colors/conversions.py
index d8a2f0b..67bcdbe 100644
--- a/bibliopixel/colors/hue.py
+++ b/bibliopixel/colors/conversions.py
@@ -205,19 +205,6 @@ hsv2rgb = hsv2rgb_rainbow
 hue2rgb = hue2rgb_rainbow
 
 
-def hex2rgb(hex):
-    """Helper for converting RGB and RGBA hex values to Color"""
-    hex = hex.strip('#')
-    if len(hex) == 6:
-        split = (hex[0:2], hex[2:4], hex[4:6])
-    else:
-        raise ValueError('Must pass in a 6 character hex value!')
-
-    r, g, b = [int(x, 16) for x in split]
-
-    return (r, g, b)
-
-
 def hue_gradient(start, stop, steps):
     assert (start >= 0 and start < 256) and (
         stop >= 0 and stop < 256), "hue must be between 0 and 255"
diff --git a/bibliopixel/colors/names.py b/bibliopixel/colors/names.py
index 5490ee9..a8c8bfa 100644
--- a/bibliopixel/colors/names.py
+++ b/bibliopixel/colors/names.py
@@ -34,6 +34,15 @@ def _classic_pairs():
             yield key, getattr(classic, name)
 
 
+def _from_number(s):
+    s = s.strip()
+    for prefix in '0x', '#':
+        if s.startswith(prefix):
+            return int(s[len(prefix):], 16)
+
+    return int(s)
+
+
 JUCE_COLORS = {k: _to_triplet(v) for k, v in juce.COLORS.items()}
 CLASSIC_COLORS = dict(_classic_pairs())
 COLOR_DICT = dict(CLASSIC_COLORS, **JUCE_COLORS)
@@ -44,34 +53,26 @@ TO_COLOR = {k.replace(' ', ''): v for k, v in COLOR_DICT.items()}
 
 
 def name_to_color(name):
-    def to_int(s):
-        s = s.strip()
-        try:
-            if s.startswith('0x'):
-                return int(s[2:], 16)
-            return int(s)
-        except:
-            raise ValueError("Don't understand number " + s)
-
-    name = name.lower()
-    if ',' in name:
-        if name.startswith('(') and name.endswith(')'):
-            name = name[1:-1]
+    def to_color(name):
+        name = name.lower()
+        if ',' in name:
+            if name.startswith('(') and name.endswith(')'):
+                name = name[1:-1]
 
-        parts = name.split(',')
-        if len(parts) != 3:
-            raise ValueError('Colors must have three components')
+            r, g, b = name.split(',')
+            return _from_number(r), _from_number(g), _from_number(b)
 
-        color = tuple(to_int(p) for p in parts)
-
-    elif name.startswith('0x'):
-        color = _to_triplet(int(name, 16))
-
-    else:
         try:
-            color = TO_COLOR[name.replace(' ', '').lower()]
+            n = _from_number(name)
         except:
-            raise ValueError('Unknown color name %s' % name)
+            return TO_COLOR[name.replace(' ', '').lower()]
+
+        return _to_triplet(n)
+
+    try:
+        color = to_color(name)
+    except:
+        raise ValueError('Unknown color name %s' % name)
 
     if not all(0 <= i <= 255 for i in color):
         raise ValueError('Component out of range: %s' % color)
@@ -88,8 +89,9 @@ def color_to_name(color):
 
 def toggle(s):
     """Toggle between a name and a tuple representation."""
+    is_numeric = ',' in s or s.startswith('0x') or s.startswith('#')
     c = name_to_color(s)
-    return color_to_name(c) if ',' in s else str(c)
+    return color_to_name(c) if is_numeric else str(c)
 
 
 class Colors(object):


Test patch:
diff --git a/test/color_test.py b/test/color_test.py
index 52560bf..c7d3d25 100644
--- a/test/color_test.py
+++ b/test/color_test.py
@@ -61,3 +61,6 @@ class NamesTest(unittest.TestCase):
         self.assertEquals(names.toggle('o n'), '(255, 255, 255)')
         self.assertEquals(names.toggle('(0, 0, 0)'), 'black')
         self.assertEquals(names.toggle('(0x8a, 0x36, 0x0f)'), 'burnt sienna')
+
+        self.assertEquals(names.toggle('#8a360f'), 'burnt sienna')
+        self.assertEquals(names.toggle('0x8a360f'), 'burnt sienna')