Skip to content

Commit

Permalink
Add exponential decay (#189)
Browse files Browse the repository at this point in the history
* added exponential decay
* updated docstring
* fixed flake8
  • Loading branch information
milonimrod authored Jan 20, 2023
1 parent a33a3f2 commit d82b23c
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
3 changes: 2 additions & 1 deletion backoff/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
"""
from backoff._decorator import on_exception, on_predicate
from backoff._jitter import full_jitter, random_jitter
from backoff._wait_gen import constant, expo, fibo, runtime
from backoff._wait_gen import constant, expo, fibo, runtime, decay

__all__ = [
'on_predicate',
'on_exception',
'constant',
'expo',
'decay',
'fibo',
'runtime',
'full_jitter',
Expand Down
30 changes: 30 additions & 0 deletions backoff/_wait_gen.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# coding:utf-8

import itertools
import math
from typing import Any, Callable, Generator, Iterable, Optional, Union


Expand Down Expand Up @@ -31,6 +32,35 @@ def expo(
yield max_value


def decay(
initial_value: float = 1,
decay_factor: float = 1,
min_value: Optional[float] = None
) -> Generator[float, Any, None]:

"""Generator for exponential decay[1]:
Args:
initial_value: initial quantity
decay_factor: exponential decay constant.
min_value: The minimum value to yield. Once the value in the
true exponential sequence is lower than this, the value
of min_value will forever after be yielded.
[1] https://en.wikipedia.org/wiki/Exponential_decay
"""
# Advance past initial .send() call
yield # type: ignore[misc]
t = 0
while True:
a = initial_value * math.e ** (-t * decay_factor)
if min_value is None or a > min_value:
yield a
t += 1
else:
yield min_value


def fibo(max_value: Optional[int] = None) -> Generator[int, None, None]:
"""Generator for fibonaccial decay.
Expand Down
29 changes: 29 additions & 0 deletions tests/test_wait_gen.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# coding:utf-8
import backoff
import math


def test_decay():
gen = backoff.decay()
gen.send(None)
for i in range(10):
assert math.e ** -i == next(gen)


def test_decay_init100():
gen = backoff.decay(initial_value=100)
gen.send(None)
for i in range(10):
assert 100 * math.e ** -i == next(gen)


def test_decay_init100_decay3():
gen = backoff.decay(initial_value=100, decay_factor=3)
gen.send(None)
for i in range(10):
assert 100 * math.e ** (-i * 3) == next(gen)


def test_decay_init100_decay3_min5():
gen = backoff.decay(initial_value=100, decay_factor=3, min_value=5)
gen.send(None)
for i in range(10):
assert max(100 * math.e ** (-i * 3), 5) == next(gen)


def test_expo():
Expand Down

0 comments on commit d82b23c

Please sign in to comment.