Skip to content

Commit

Permalink
Using a topline to provide flexibility in the sum of the original rec…
Browse files Browse the repository at this point in the history
…ords
  • Loading branch information
Manikandan Nagarajan authored and Calvin DeBoer committed Sep 16, 2021
1 parent ac07389 commit 40ca2cf
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 4 deletions.
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ Iteround is written and maintained by Calvin DeBoer.
Authors
```````````````````````
- Calvin DeBoer <cgdeboer@gmail.com> `@cgdeboer <https://github.com/cgdeboer>`_
- Manikandan Nagarajan <manikandan_nagarajan@ymail.com> `@M22an <https://github.com/M22an>`_
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ iterable (list, dict, set, numpy.array, generator): list(y) of numbers

places (int): Places for rounding.
Number of places each item in the set should be rounded to.

topline (float, optional): Topline to match
Useful in places where we want the total sum to match a different topline
than the sum of iterable. This can useful in cases where original values
are altered before passing into the saferound method, but the original sum
needs to be maintained.

strategy (str, optional): The strategy used to clean up rounding errors
'difference', 'largest', 'smallest'. Defaults to 'difference'
Expand Down
12 changes: 10 additions & 2 deletions iteround/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
DIFFERENCE = 'difference'


def saferound(iterable, places, strategy=DIFFERENCE, rounder=round):
def saferound(iterable, places, strategy=DIFFERENCE, rounder=round, topline=None):
"""Rounds an iterable of floats while retaining the original summed value.
Function parameters should be documented in the ``Args`` section. The name
Expand Down Expand Up @@ -39,6 +39,12 @@ def saferound(iterable, places, strategy=DIFFERENCE, rounder=round):
rounder method must take 2 arguments, a `float` to be rounded, and
an integer for the number of places (with support for negative)
topline (float, optional): Topline to match
Useful in places where we want the total sum to match a different
topline than the sum of iterable. This can useful in cases where
original values are altered before passing into the saferound
method, but the original sum needs to be maintained.
Returns:
iterable (same type as input, but with rounded values).
Expand All @@ -65,7 +71,9 @@ def saferound(iterable, places, strategy=DIFFERENCE, rounder=round):

# calculate original sum, rounded, then rounded local sum.
local = [Number(i, value) for i, value in enumerate(values)]
orig_sum = _sumnum(local, places, rounder)
orig_sum = (_sumnum(local, places, rounder)
if topline is None else
rounder(topline, places))
[n.round(places, rounder) for n in local]
local_sum = _sumnum(local, places, rounder)

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="iteround",
version="1.0.2",
version="1.0.3",
author="Calvin DeBoer",
author_email="cgdeboer@gmail.com",
description=("Rounds iterables (arrays, lists, sets, etc) "
Expand Down
14 changes: 13 additions & 1 deletion tests/test_saferound.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import iteround
from collections import OrderedDict


class TestSafeRoundMethods(unittest.TestCase):

def setUp(self):
Expand Down Expand Up @@ -79,6 +78,19 @@ def test_over_with_sum(self):
out = [0.0, 0.0, 0.0, 10.0, 10.0, 10.0]
self.assertListEqual(iteround.saferound(self.in_list, -1), out)

def test_topline(self):
out = [4.0, 3.0, 3.0, 7.0, 5.0, 7.0]
topline = 29
actual_out = iteround.saferound(self.in_list, 0, topline=topline)
actual_topline = sum(actual_out)
self.assertListEqual(actual_out, out)
self.assertEqual(topline, actual_topline)

def test_topline_sum(self):
self.assertEqual(sum(iteround.saferound(self.in_list, 0, topline=28)), 28)
self.assertEqual(sum(iteround.saferound(self.in_list, 0, topline=29)), 29)
self.assertEqual(sum(iteround.saferound(self.in_list, 0, topline=30)), 30)


if __name__ == '__main__':
unittest.main()

0 comments on commit 40ca2cf

Please sign in to comment.