11"""
22Functionality relating to individual colours.
33"""
4+ from __future__ import annotations
5+
6+ import re
47from dataclasses import dataclass
5- from typing import Tuple
8+ from typing import Tuple , Any
69
710
811@dataclass (frozen = True )
@@ -16,9 +19,25 @@ class Colour:
1619 @property
1720 def rgb (self ) -> Tuple [int , int , int ]:
1821 """Get the colour as a 3-tuple of red, green, and blue."""
19- return ( self .red , self .green , self .blue )
22+ return self .red , self .green , self .blue
2023
2124 @property
2225 def hex (self ) -> str :
2326 """Get the colour as a lowercase hex string."""
2427 return f"{ self .red :02x} { self .green :02x} { self .blue :02x} "
28+
29+ def __eq__ (self , other : Any ) -> bool :
30+ if not isinstance (other , Colour ):
31+ raise ValueError ("Cannot check equality with non-colour types." )
32+ return self .hex == other .hex
33+
34+ @classmethod
35+ def from_hex (cls , hex_string : str ) -> Colour :
36+ """Create a color from hex string."""
37+ if len (hex_string ) != 6 :
38+ raise ValueError ("Hex string must be 6 characters long." )
39+ match = re .match (r"([\da-fA-F]{2})" * 3 , hex_string )
40+ if match is None :
41+ raise ValueError ("Hex string have an invalid format." )
42+ r , g , b = match .groups ()
43+ return Colour (* (int (col , 16 ) for col in (r , g , b )))
0 commit comments