Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add round method to checks base #2931

Merged
merged 4 commits into from
Jan 14, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions datadog_checks_base/datadog_checks/base/utils/common.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# (C) Datadog, Inc. 2018
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
from decimal import ROUND_HALF_UP, Decimal, getcontext
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from decimal import ROUND_HALF_UP, Decimal, getcontext
from decimal import ROUND_HALF_UP, Decimal

import os
import re

Expand All @@ -23,6 +24,11 @@ def ensure_unicode(s):
to_string = ensure_unicode if PY3 else ensure_bytes


def round_value(value, sig_digits="0.01", rounding_method=ROUND_HALF_UP):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, sig_digits can be a float.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same consideration as above 🙂

getcontext().rounding = rounding_method
return float(Decimal(str(value)).quantize(Decimal(sig_digits)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to convert to string before passing to decimal

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do actually to get proper arithmetic

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there are interesting behaviors when you don't appropriately cast to string. The documentation for Decimal also has all floating point examples in string format - https://docs.python.org/2/library/decimal.html

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def round_num(value, precision=0):
    return float(Decimal(str(value)).quantize(Decimal('0.{}'.format('0' * precision)), rounding=ROUND_HALF_UP))

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like leaving it open to modify the rounding strategy if anyone requires something like Python 3s ROUND_HALF_EVEN function later. I don't think it hurts to leave it in the signature as an optional parameter

I do like the precision component!



def get_docker_hostname():
return urlparse(os.getenv('DOCKER_HOST', '')).hostname or 'localhost'

Expand Down
17 changes: 16 additions & 1 deletion datadog_checks_base/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# (C) Datadog, Inc. 2018
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
from decimal import ROUND_HALF_DOWN, ROUND_HALF_UP

from datadog_checks.utils.common import pattern_filter
from datadog_checks.utils.common import pattern_filter, round_value
from datadog_checks.utils.limiter import Limiter


Expand Down Expand Up @@ -105,3 +106,17 @@ def test_reset(self):
assert limiter.get_status() == (0, 10, False)
assert limiter.is_reached("dummy1") is False
assert limiter.get_status() == (1, 10, False)


class TestRounding():
def test_round_half_up(self):
assert round_value(2.555) == 2.560
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert round_value(2.555) == 2.560
assert round_num(2.5) == 3


def test_round_modify_method(self):
assert round_value(3.5, sig_digits="1", rounding_method=ROUND_HALF_DOWN) == 3.0

def test_round_modify_sig_digits(self):
assert round_value(3.5, sig_digits="1") == 4.0
assert round_value(2.555, sig_digits="0.01") == 2.560
assert round_value(4.2345, sig_digits="0.01") == 4.23
assert round_value(4.2345, sig_digits="0.000") == 4.235