Home Assistant Unofficial Reference 2024.12.1
percentage.py
Go to the documentation of this file.
1 """Percentage util functions."""
2 
3 from __future__ import annotations
4 
5 from .scaling import ( # noqa: F401
6  int_states_in_range,
7  scale_ranged_value_to_int_range,
8  scale_to_ranged_value,
9  states_in_range,
10 )
11 
12 
13 def ordered_list_item_to_percentage[_T](ordered_list: list[_T], item: _T) -> int:
14  """Determine the percentage of an item in an ordered list.
15 
16  When using this utility for fan speeds, do not include "off"
17 
18  Given the list: ["low", "medium", "high", "very_high"], this
19  function will return the following when the item is passed
20  in:
21 
22  low: 25
23  medium: 50
24  high: 75
25  very_high: 100
26 
27  """
28  if item not in ordered_list:
29  raise ValueError(f'The item "{item}" is not in "{ordered_list}"')
30 
31  list_len = len(ordered_list)
32  list_position = ordered_list.index(item) + 1
33  return (list_position * 100) // list_len
34 
35 
36 def percentage_to_ordered_list_item[_T](ordered_list: list[_T], percentage: int) -> _T:
37  """Find the item that most closely matches the percentage in an ordered list.
38 
39  When using this utility for fan speeds, do not include "off"
40 
41  Given the list: ["low", "medium", "high", "very_high"], this
42  function will return the following when when the item is passed
43  in:
44 
45  1-25: low
46  26-50: medium
47  51-75: high
48  76-100: very_high
49  """
50  if not (list_len := len(ordered_list)):
51  raise ValueError("The ordered list is empty")
52 
53  for offset, speed in enumerate(ordered_list):
54  list_position = offset + 1
55  upper_bound = (list_position * 100) // list_len
56  if percentage <= upper_bound:
57  return speed
58 
59  return ordered_list[-1]
60 
61 
63  low_high_range: tuple[float, float], value: float
64 ) -> int:
65  """Given a range of low and high values convert a single value to a percentage.
66 
67  When using this utility for fan speeds, do not include 0 if it is off
68 
69  Given a low value of 1 and a high value of 255 this function
70  will return:
71 
72  (1,255), 255: 100
73  (1,255), 127: 50
74  (1,255), 10: 4
75  """
76  return scale_ranged_value_to_int_range(low_high_range, (1, 100), value)
77 
78 
80  low_high_range: tuple[float, float], percentage: float
81 ) -> float:
82  """Given a range of low and high values convert a percentage to a single value.
83 
84  When using this utility for fan speeds, do not include 0 if it is off
85 
86  Given a low value of 1 and a high value of 255 this function
87  will return:
88 
89  (1,255), 100: 255
90  (1,255), 50: 127.5
91  (1,255), 4: 10.2
92  """
93  return scale_to_ranged_value((1, 100), low_high_range, percentage)
float percentage_to_ranged_value(tuple[float, float] low_high_range, float percentage)
Definition: percentage.py:81
int ranged_value_to_percentage(tuple[float, float] low_high_range, float value)
Definition: percentage.py:64
int scale_ranged_value_to_int_range(tuple[float, float] source_low_high_range, tuple[float, float] target_low_high_range, float value)
Definition: scaling.py:10
float scale_to_ranged_value(tuple[float, float] source_low_high_range, tuple[float, float] target_low_high_range, float value)
Definition: scaling.py:35