Add support for logarithm in templates (#10824)

* Add support for logarithm in templates

This adds a 'log' filter that takes the logarithm of the given value,
with an optional base number. The base defaults to 'e' - the natural
logarithm

* Remove usage of log10 in template filter 'log'

* Add logarithm as a global

This makes it possible to write:
'{{ log(4, 2) }}'
pull/10091/merge
Odin Ugedal 2017-11-28 06:29:01 +01:00 committed by Paulus Schoutsen
parent 27270b49b4
commit 0668fba7bd
2 changed files with 35 additions and 0 deletions

View File

@ -4,6 +4,7 @@ import json
import logging
import random
import re
import math
import jinja2
from jinja2 import contextfilter
@ -423,6 +424,14 @@ def multiply(value, amount):
return value
def logarithm(value, base=math.e):
"""Filter to get logarithm of the value with a spesific base."""
try:
return math.log(float(value), float(base))
except (ValueError, TypeError):
return value
def timestamp_custom(value, date_format=DATE_STR_FORMAT, local=True):
"""Filter to convert given timestamp to format."""
try:
@ -508,6 +517,7 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
ENV = TemplateEnvironment()
ENV.filters['round'] = forgiving_round
ENV.filters['multiply'] = multiply
ENV.filters['log'] = logarithm
ENV.filters['timestamp_custom'] = timestamp_custom
ENV.filters['timestamp_local'] = timestamp_local
ENV.filters['timestamp_utc'] = timestamp_utc
@ -515,6 +525,7 @@ ENV.filters['is_defined'] = fail_when_undefined
ENV.filters['max'] = max
ENV.filters['min'] = min
ENV.filters['random'] = random_every_time
ENV.globals['log'] = logarithm
ENV.globals['float'] = forgiving_float
ENV.globals['now'] = dt_util.now
ENV.globals['utcnow'] = dt_util.utcnow

View File

@ -3,6 +3,7 @@ import asyncio
from datetime import datetime
import unittest
import random
import math
from unittest.mock import patch
from homeassistant.components import group
@ -125,6 +126,29 @@ class TestHelpersTemplate(unittest.TestCase):
template.Template('{{ %s | multiply(10) | round }}' % inp,
self.hass).render())
def test_logarithm(self):
"""Test logarithm."""
tests = [
(4, 2, '2.0'),
(1000, 10, '3.0'),
(math.e, '', '1.0'),
('"invalid"', '_', 'invalid'),
(10, '"invalid"', '10.0'),
]
for value, base, expected in tests:
self.assertEqual(
expected,
template.Template(
'{{ %s | log(%s) | round(1) }}' % (value, base),
self.hass).render())
self.assertEqual(
expected,
template.Template(
'{{ log(%s, %s) | round(1) }}' % (value, base),
self.hass).render())
def test_strptime(self):
"""Test the parse timestamp method."""
tests = [