mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 16:57:10 +00:00
Add average template function and filter (#57727)
This commit is contained in:
parent
953ad71d22
commit
11034a93c3
@ -16,6 +16,7 @@ import math
|
|||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
|
import statistics
|
||||||
import sys
|
import sys
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
from urllib.parse import urlencode as urllib_urlencode
|
from urllib.parse import urlencode as urllib_urlencode
|
||||||
@ -1489,6 +1490,24 @@ def fail_when_undefined(value):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def average(*args: Any) -> float:
|
||||||
|
"""
|
||||||
|
Filter and function to calculate the arithmetic mean of an iterable or of two or more arguments.
|
||||||
|
|
||||||
|
The parameters may be passed as an iterable or as separate arguments.
|
||||||
|
"""
|
||||||
|
if len(args) == 0:
|
||||||
|
raise TypeError("average expected at least 1 argument, got 0")
|
||||||
|
|
||||||
|
if len(args) == 1:
|
||||||
|
if isinstance(args[0], Iterable):
|
||||||
|
return statistics.fmean(args[0])
|
||||||
|
|
||||||
|
raise TypeError(f"'{type(args[0]).__name__}' object is not iterable")
|
||||||
|
|
||||||
|
return statistics.fmean(args)
|
||||||
|
|
||||||
|
|
||||||
def forgiving_float(value, default=_SENTINEL):
|
def forgiving_float(value, default=_SENTINEL):
|
||||||
"""Try to convert value to a float."""
|
"""Try to convert value to a float."""
|
||||||
try:
|
try:
|
||||||
@ -1758,6 +1777,7 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
|
|||||||
self.filters["to_json"] = to_json
|
self.filters["to_json"] = to_json
|
||||||
self.filters["from_json"] = from_json
|
self.filters["from_json"] = from_json
|
||||||
self.filters["is_defined"] = fail_when_undefined
|
self.filters["is_defined"] = fail_when_undefined
|
||||||
|
self.filters["average"] = average
|
||||||
self.filters["max"] = max
|
self.filters["max"] = max
|
||||||
self.filters["min"] = min
|
self.filters["min"] = min
|
||||||
self.filters["random"] = random_every_time
|
self.filters["random"] = random_every_time
|
||||||
@ -1796,6 +1816,7 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
|
|||||||
self.globals["timedelta"] = timedelta
|
self.globals["timedelta"] = timedelta
|
||||||
self.globals["strptime"] = strptime
|
self.globals["strptime"] = strptime
|
||||||
self.globals["urlencode"] = urlencode
|
self.globals["urlencode"] = urlencode
|
||||||
|
self.globals["average"] = average
|
||||||
self.globals["max"] = max
|
self.globals["max"] = max
|
||||||
self.globals["min"] = min
|
self.globals["min"] = min
|
||||||
self.globals["is_number"] = is_number
|
self.globals["is_number"] = is_number
|
||||||
|
@ -758,6 +758,19 @@ def test_from_json(hass):
|
|||||||
assert actual_result == expected_result
|
assert actual_result == expected_result
|
||||||
|
|
||||||
|
|
||||||
|
def test_average(hass):
|
||||||
|
"""Test the average filter."""
|
||||||
|
assert template.Template("{{ [1, 2, 3] | average }}", hass).async_render() == 2
|
||||||
|
assert template.Template("{{ average([1, 2, 3]) }}", hass).async_render() == 2
|
||||||
|
assert template.Template("{{ average(1, 2, 3) }}", hass).async_render() == 2
|
||||||
|
|
||||||
|
with pytest.raises(TemplateError):
|
||||||
|
template.Template("{{ 1 | average }}", hass).async_render()
|
||||||
|
|
||||||
|
with pytest.raises(TemplateError):
|
||||||
|
template.Template("{{ average() }}", hass).async_render()
|
||||||
|
|
||||||
|
|
||||||
def test_min(hass):
|
def test_min(hass):
|
||||||
"""Test the min filter."""
|
"""Test the min filter."""
|
||||||
assert template.Template("{{ [1, 2, 3] | min }}", hass).async_render() == 1
|
assert template.Template("{{ [1, 2, 3] | min }}", hass).async_render() == 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user