Skip to content

Instantly share code, notes, and snippets.

@hartwork
Last active February 9, 2025 19:16
Show Gist options
  • Save hartwork/9c41958d1d0add5ed76b5f9d58160e21 to your computer and use it in GitHub Desktop.
Save hartwork/9c41958d1d0add5ed76b5f9d58160e21 to your computer and use it in GitHub Desktop.
#! /usr/bin/env python3
# Copyright (c) 2025 Sebastian Pipping <[email protected]>
# Licensed under the MIT license
import decimal
import math
import sys
from decimal import Decimal
import pylab
from matplotlib import pyplot
PERCENT_FORMAT = "PERCENT_FORMATTING"
HUMAN_ROUNDING = decimal.ROUND_HALF_UP
NO_DECIMAL_PLACES = Decimal("0")
def create_label(rounding_mode: str) -> str:
if rounding_mode == decimal.ROUND_HALF_EVEN:
return f"Python decimal default (i.e. decimal.{rounding_mode})"
elif rounding_mode == HUMAN_ROUNDING:
return f"Human default (i.e. decimal.{rounding_mode})"
elif rounding_mode == PERCENT_FORMAT:
return f"Percent formatting (i.e. decimal.ROUND_HALF_EVEN)"
return f"decimal.{rounding_mode}"
def values_for_rounding_mode(rounding_mode: str, x_values: list[float]) -> list[float]:
if rounding_mode == PERCENT_FORMAT:
return [Decimal("%.0f" % x) for x in x_values]
with decimal.localcontext(rounding=rounding_mode):
return [x.quantize(NO_DECIMAL_PLACES) for x in x_values]
if __name__ == '__main__':
if sys.version_info < (3, 11):
sys.exit("ERROR: Python >=3.11 is needed.")
ROUNDING_MODES = [getattr(decimal, k) for k in dir(decimal) if k.startswith('ROUND_')]
X = [Decimal(i / 10) for i in range(-20, 20 + 1)]
Y_HUMAN = values_for_rounding_mode(decimal.ROUND_HALF_UP, X)
for rounding_mode in ROUNDING_MODES + [PERCENT_FORMAT]:
Y = values_for_rounding_mode(rounding_mode, X)
pyplot.clf()
pyplot.grid(visible=True, which='major', axis='both')
pyplot.scatter(X, X, label="id(x)", marker='o')
if rounding_mode != HUMAN_ROUNDING: # to not plot the the same thing twice
pyplot.scatter(X, Y_HUMAN, label=create_label(decimal.ROUND_HALF_UP), marker='o')
pyplot.scatter(X, Y, label=create_label(rounding_mode), marker='.')
pyplot.legend()
filename = f"{rounding_mode.lower()}.svg"
print(f"Writing file {filename!r}...")
pyplot.savefig(filename)
print("Done.")
@hartwork
Copy link
Author

hartwork commented Feb 9, 2025

Expected output

percent_formatting.svg

percent_formatting

round_05up.svg

round_05up

round_ceiling.svg

round_ceiling

round_down.svg

round_down

round_floor.svg

round_floor

round_half_down.svg

round_half_down

round_half_even.svg

round_half_even

round_half_up.svg

round_half_up

round_up.svg

round_up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment