Add optional default value to average template function/filter (#77499)
* Return None on empty list * Updated to use default value * Update comment.
This commit is contained in:
parent
61f0d0ea15
commit
47b40e1e61
2 changed files with 31 additions and 6 deletions
|
@ -1657,7 +1657,7 @@ def min_max_from_filter(builtin_filter: Any, name: str) -> Any:
|
|||
return pass_environment(wrapper)
|
||||
|
||||
|
||||
def average(*args: Any) -> float:
|
||||
def average(*args: Any, default: Any = _SENTINEL) -> Any:
|
||||
"""
|
||||
Filter and function to calculate the arithmetic mean of an iterable or of two or more arguments.
|
||||
|
||||
|
@ -1666,13 +1666,23 @@ def average(*args: Any) -> float:
|
|||
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])
|
||||
|
||||
# If first argument is iterable and more then 1 argument provided but not a named default,
|
||||
# then use 2nd argument as default.
|
||||
if isinstance(args[0], Iterable):
|
||||
average_list = args[0]
|
||||
if len(args) > 1 and default is _SENTINEL:
|
||||
default = args[1]
|
||||
elif len(args) == 1:
|
||||
raise TypeError(f"'{type(args[0]).__name__}' object is not iterable")
|
||||
else:
|
||||
average_list = args
|
||||
|
||||
return statistics.fmean(args)
|
||||
try:
|
||||
return statistics.fmean(average_list)
|
||||
except (TypeError, statistics.StatisticsError):
|
||||
if default is _SENTINEL:
|
||||
raise_no_default("average", args)
|
||||
return default
|
||||
|
||||
|
||||
def forgiving_float(value, default=_SENTINEL):
|
||||
|
|
|
@ -973,12 +973,27 @@ def test_average(hass):
|
|||
assert template.Template("{{ average([1, 2, 3]) }}", hass).async_render() == 2
|
||||
assert template.Template("{{ average(1, 2, 3) }}", hass).async_render() == 2
|
||||
|
||||
# Testing of default values
|
||||
assert template.Template("{{ average([1, 2, 3], -1) }}", hass).async_render() == 2
|
||||
assert template.Template("{{ average([], -1) }}", hass).async_render() == -1
|
||||
assert template.Template("{{ average([], default=-1) }}", hass).async_render() == -1
|
||||
assert (
|
||||
template.Template("{{ average([], 5, default=-1) }}", hass).async_render() == -1
|
||||
)
|
||||
assert (
|
||||
template.Template("{{ average(1, 'a', 3, default=-1) }}", hass).async_render()
|
||||
== -1
|
||||
)
|
||||
|
||||
with pytest.raises(TemplateError):
|
||||
template.Template("{{ 1 | average }}", hass).async_render()
|
||||
|
||||
with pytest.raises(TemplateError):
|
||||
template.Template("{{ average() }}", hass).async_render()
|
||||
|
||||
with pytest.raises(TemplateError):
|
||||
template.Template("{{ average([]) }}", hass).async_render()
|
||||
|
||||
|
||||
def test_min(hass):
|
||||
"""Test the min filter."""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue