84 lines
2.4 KiB
Python
84 lines
2.4 KiB
Python
"""Helper functions for the Adaptive Lighting custom components."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import base64
|
|
import math
|
|
|
|
|
|
def clamp(value: float, minimum: float, maximum: float) -> float:
|
|
"""Clamp value between minimum and maximum."""
|
|
return max(minimum, min(value, maximum))
|
|
|
|
|
|
def int_to_base36(num: int) -> str:
|
|
"""Convert an integer to its base-36 representation using numbers and uppercase letters.
|
|
|
|
Base-36 encoding uses digits 0-9 and uppercase letters A-Z, providing a case-insensitive
|
|
alphanumeric representation. The function takes an integer `num` as input and returns
|
|
its base-36 representation as a string.
|
|
|
|
Parameters
|
|
----------
|
|
num
|
|
The integer to convert to base-36.
|
|
|
|
Returns
|
|
-------
|
|
str
|
|
The base-36 representation of the input integer.
|
|
|
|
Examples
|
|
--------
|
|
>>> num = 123456
|
|
>>> base36_num = int_to_base36(num)
|
|
>>> print(base36_num)
|
|
'2N9'
|
|
"""
|
|
alphanumeric_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
|
|
if num == 0:
|
|
return alphanumeric_chars[0]
|
|
|
|
base36_str = ""
|
|
base = len(alphanumeric_chars)
|
|
|
|
while num:
|
|
num, remainder = divmod(num, base)
|
|
base36_str = alphanumeric_chars[remainder] + base36_str
|
|
|
|
return base36_str
|
|
|
|
|
|
def short_hash(string: str, length: int = 4) -> str:
|
|
"""Create a hash of 'string' with length 'length'."""
|
|
return base64.b32encode(string.encode()).decode("utf-8").zfill(length)[:length]
|
|
|
|
|
|
def remove_vowels(input_str: str, length: int = 4) -> str:
|
|
"""Remove vowels from a string and return a string of length 'length'."""
|
|
vowels = "aeiouAEIOU"
|
|
output_str = "".join([char for char in input_str if char not in vowels])
|
|
return output_str.zfill(length)[:length]
|
|
|
|
|
|
def color_difference_redmean(
|
|
rgb1: tuple[float, float, float],
|
|
rgb2: tuple[float, float, float],
|
|
) -> float:
|
|
"""Distance between colors in RGB space (redmean metric).
|
|
|
|
The maximal distance between (255, 255, 255) and (0, 0, 0) ≈ 765.
|
|
|
|
Sources:
|
|
- https://en.wikipedia.org/wiki/Color_difference#Euclidean
|
|
- https://www.compuphase.com/cmetric.htm
|
|
"""
|
|
r_hat = (rgb1[0] + rgb2[0]) / 2
|
|
delta_r, delta_g, delta_b = (
|
|
(col1 - col2) for col1, col2 in zip(rgb1, rgb2, strict=True)
|
|
)
|
|
red_term = (2 + r_hat / 256) * delta_r**2
|
|
green_term = 4 * delta_g**2
|
|
blue_term = (2 + (255 - r_hat) / 256) * delta_b**2
|
|
return math.sqrt(red_term + green_term + blue_term)
|