Added "plus_sign" option to currency format/parsing.

This commit is contained in:
s3lph 2018-09-01 17:07:49 +02:00
parent ff0c13d367
commit 6901729ac3
2 changed files with 64 additions and 2 deletions

View file

@ -1,11 +1,12 @@
def format_chf(value: int, with_currencysign: bool = True) -> str: def format_chf(value: int, with_currencysign: bool = True, plus_sign: bool = False) -> str:
""" """
Formats a centime value into a commonly understood representation ("CHF -13.37"). Formats a centime value into a commonly understood representation ("CHF -13.37").
:param value: The value to format, in centimes. :param value: The value to format, in centimes.
:param with_currencysign: Whether to include the currency prefix ("CHF ") in the output. :param with_currencysign: Whether to include the currency prefix ("CHF ") in the output.
:param plus_sign: Whether to denote positive values with an explicit "+" sign before the value.
:return: A human-readable string representation. :return: A human-readable string representation.
""" """
sign: str = '' sign: str = ''
@ -13,6 +14,8 @@ def format_chf(value: int, with_currencysign: bool = True) -> str:
# As // and % round towards -Inf, convert into a positive value and prepend the negative sign # As // and % round towards -Inf, convert into a positive value and prepend the negative sign
sign = '-' sign = '-'
value = -value value = -value
elif plus_sign:
sign = '+'
# Split into full francs and fractions (centimes) # Split into full francs and fractions (centimes)
full: int = value // 100 full: int = value // 100
frac: int = value % 100 frac: int = value % 100

View file

@ -9,38 +9,56 @@ class TestCurrencyFormat(unittest.TestCase):
def test_format_zero(self): def test_format_zero(self):
self.assertEqual('CHF 0.00', format_chf(0)) self.assertEqual('CHF 0.00', format_chf(0))
self.assertEqual('0.00', format_chf(0, False)) self.assertEqual('0.00', format_chf(0, False))
self.assertEqual('CHF +0.00', format_chf(0, plus_sign=True))
self.assertEqual('+0.00', format_chf(0, False, plus_sign=True))
def test_format_positive_full(self): def test_format_positive_full(self):
self.assertEqual('CHF 42.00', format_chf(4200)) self.assertEqual('CHF 42.00', format_chf(4200))
self.assertEqual('42.00', format_chf(4200, False)) self.assertEqual('42.00', format_chf(4200, False))
self.assertEqual('CHF +42.00', format_chf(4200, plus_sign=True))
self.assertEqual('+42.00', format_chf(4200, False, plus_sign=True))
def test_format_negative_full(self): def test_format_negative_full(self):
self.assertEqual('CHF -42.00', format_chf(-4200)) self.assertEqual('CHF -42.00', format_chf(-4200))
self.assertEqual('-42.00', format_chf(-4200, False)) self.assertEqual('-42.00', format_chf(-4200, False))
self.assertEqual('CHF -42.00', format_chf(-4200, plus_sign=True))
self.assertEqual('-42.00', format_chf(-4200, False, plus_sign=True))
def test_format_positive_frac(self): def test_format_positive_frac(self):
self.assertEqual('CHF 13.37', format_chf(1337)) self.assertEqual('CHF 13.37', format_chf(1337))
self.assertEqual('13.37', format_chf(1337, False)) self.assertEqual('13.37', format_chf(1337, False))
self.assertEqual('CHF +13.37', format_chf(1337, plus_sign=True))
self.assertEqual('+13.37', format_chf(1337, False, plus_sign=True))
def test_format_negative_frac(self): def test_format_negative_frac(self):
self.assertEqual('CHF -13.37', format_chf(-1337)) self.assertEqual('CHF -13.37', format_chf(-1337))
self.assertEqual('-13.37', format_chf(-1337, False)) self.assertEqual('-13.37', format_chf(-1337, False))
self.assertEqual('CHF -13.37', format_chf(-1337, plus_sign=True))
self.assertEqual('-13.37', format_chf(-1337, False, plus_sign=True))
def test_format_pad_left_positive(self): def test_format_pad_left_positive(self):
self.assertEqual('CHF 0.01', format_chf(1)) self.assertEqual('CHF 0.01', format_chf(1))
self.assertEqual('0.01', format_chf(1, False)) self.assertEqual('0.01', format_chf(1, False))
self.assertEqual('CHF +0.01', format_chf(1, plus_sign=True))
self.assertEqual('+0.01', format_chf(1, False, plus_sign=True))
def test_format_pad_left_negative(self): def test_format_pad_left_negative(self):
self.assertEqual('CHF -0.01', format_chf(-1)) self.assertEqual('CHF -0.01', format_chf(-1))
self.assertEqual('-0.01', format_chf(-1, False)) self.assertEqual('-0.01', format_chf(-1, False))
self.assertEqual('CHF -0.01', format_chf(-1, plus_sign=True))
self.assertEqual('-0.01', format_chf(-1, False, plus_sign=True))
def test_format_pad_right_positive(self): def test_format_pad_right_positive(self):
self.assertEqual('CHF 4.20', format_chf(420)) self.assertEqual('CHF 4.20', format_chf(420))
self.assertEqual('4.20', format_chf(420, False)) self.assertEqual('4.20', format_chf(420, False))
self.assertEqual('CHF +4.20', format_chf(420, plus_sign=True))
self.assertEqual('+4.20', format_chf(420, False, plus_sign=True))
def test_format_pad_right_negative(self): def test_format_pad_right_negative(self):
self.assertEqual('CHF -4.20', format_chf(-420)) self.assertEqual('CHF -4.20', format_chf(-420))
self.assertEqual('-4.20', format_chf(-420, False)) self.assertEqual('-4.20', format_chf(-420, False))
self.assertEqual('CHF -4.20', format_chf(-420, plus_sign=True))
self.assertEqual('-4.20', format_chf(-420, False, plus_sign=True))
def test_parse_empty(self): def test_parse_empty(self):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
@ -52,20 +70,29 @@ class TestCurrencyFormat(unittest.TestCase):
def test_parse_zero(self): def test_parse_zero(self):
self.assertEqual(0, parse_chf('CHF0')) self.assertEqual(0, parse_chf('CHF0'))
self.assertEqual(0, parse_chf('CHF-0'))
self.assertEqual(0, parse_chf('CHF+0'))
self.assertEqual(0, parse_chf('CHF 0')) self.assertEqual(0, parse_chf('CHF 0'))
self.assertEqual(0, parse_chf('CHF +0'))
self.assertEqual(0, parse_chf('CHF -0')) self.assertEqual(0, parse_chf('CHF -0'))
self.assertEqual(0, parse_chf('CHF 0.')) self.assertEqual(0, parse_chf('CHF 0.'))
self.assertEqual(0, parse_chf('CHF 0.0')) self.assertEqual(0, parse_chf('CHF 0.0'))
self.assertEqual(0, parse_chf('CHF 0.00')) self.assertEqual(0, parse_chf('CHF 0.00'))
self.assertEqual(0, parse_chf('CHF +0.'))
self.assertEqual(0, parse_chf('CHF +0.0'))
self.assertEqual(0, parse_chf('CHF +0.00'))
self.assertEqual(0, parse_chf('CHF -0.')) self.assertEqual(0, parse_chf('CHF -0.'))
self.assertEqual(0, parse_chf('CHF -0.0')) self.assertEqual(0, parse_chf('CHF -0.0'))
self.assertEqual(0, parse_chf('CHF -0.00')) self.assertEqual(0, parse_chf('CHF -0.00'))
self.assertEqual(0, parse_chf('0')) self.assertEqual(0, parse_chf('0'))
self.assertEqual(0, parse_chf('0')) self.assertEqual(0, parse_chf('+0'))
self.assertEqual(0, parse_chf('-0')) self.assertEqual(0, parse_chf('-0'))
self.assertEqual(0, parse_chf('0.')) self.assertEqual(0, parse_chf('0.'))
self.assertEqual(0, parse_chf('0.0')) self.assertEqual(0, parse_chf('0.0'))
self.assertEqual(0, parse_chf('0.00')) self.assertEqual(0, parse_chf('0.00'))
self.assertEqual(0, parse_chf('+0.'))
self.assertEqual(0, parse_chf('+0.0'))
self.assertEqual(0, parse_chf('+0.00'))
self.assertEqual(0, parse_chf('-0.')) self.assertEqual(0, parse_chf('-0.'))
self.assertEqual(0, parse_chf('-0.0')) self.assertEqual(0, parse_chf('-0.0'))
self.assertEqual(0, parse_chf('-0.00')) self.assertEqual(0, parse_chf('-0.00'))
@ -80,6 +107,16 @@ class TestCurrencyFormat(unittest.TestCase):
self.assertEqual(4200, parse_chf('CHF 42.0')) self.assertEqual(4200, parse_chf('CHF 42.0'))
self.assertEqual(4200, parse_chf('42.0')) self.assertEqual(4200, parse_chf('42.0'))
def test_parse_positive_full_with_sign(self):
self.assertEqual(4200, parse_chf('CHF +42.00'))
self.assertEqual(4200, parse_chf('+42.00'))
self.assertEqual(4200, parse_chf('CHF +42'))
self.assertEqual(4200, parse_chf('+42'))
self.assertEqual(4200, parse_chf('CHF +42.'))
self.assertEqual(4200, parse_chf('+42.'))
self.assertEqual(4200, parse_chf('CHF +42.0'))
self.assertEqual(4200, parse_chf('+42.0'))
def test_parse_negative_full(self): def test_parse_negative_full(self):
self.assertEqual(-4200, parse_chf('CHF -42.00')) self.assertEqual(-4200, parse_chf('CHF -42.00'))
self.assertEqual(-4200, parse_chf('-42.00')) self.assertEqual(-4200, parse_chf('-42.00'))
@ -94,6 +131,10 @@ class TestCurrencyFormat(unittest.TestCase):
self.assertEqual(1337, parse_chf('CHF 13.37')) self.assertEqual(1337, parse_chf('CHF 13.37'))
self.assertEqual(1337, parse_chf('13.37')) self.assertEqual(1337, parse_chf('13.37'))
def test_parse_positive_frac_with_sign(self):
self.assertEqual(1337, parse_chf('CHF +13.37'))
self.assertEqual(1337, parse_chf('+13.37'))
def test_parse_negative_frac(self): def test_parse_negative_frac(self):
self.assertEqual(-1337, parse_chf('CHF -13.37')) self.assertEqual(-1337, parse_chf('CHF -13.37'))
self.assertEqual(-1337, parse_chf('-13.37')) self.assertEqual(-1337, parse_chf('-13.37'))
@ -102,6 +143,10 @@ class TestCurrencyFormat(unittest.TestCase):
self.assertEqual(1, parse_chf('CHF 0.01')) self.assertEqual(1, parse_chf('CHF 0.01'))
self.assertEqual(1, parse_chf('0.01')) self.assertEqual(1, parse_chf('0.01'))
def test_parse_pad_left_positive_with_sign(self):
self.assertEqual(1, parse_chf('CHF +0.01'))
self.assertEqual(1, parse_chf('+0.01'))
def test_parse_pad_left_negative(self): def test_parse_pad_left_negative(self):
self.assertEqual(-1, parse_chf('CHF -0.01')) self.assertEqual(-1, parse_chf('CHF -0.01'))
self.assertEqual(-1, parse_chf('-0.01')) self.assertEqual(-1, parse_chf('-0.01'))
@ -112,6 +157,12 @@ class TestCurrencyFormat(unittest.TestCase):
self.assertEqual(420, parse_chf('CHF 4.2')) self.assertEqual(420, parse_chf('CHF 4.2'))
self.assertEqual(420, parse_chf('4.2')) self.assertEqual(420, parse_chf('4.2'))
def test_parse_pad_right_positive_with_sign(self):
self.assertEqual(420, parse_chf('CHF +4.20'))
self.assertEqual(420, parse_chf('+4.20'))
self.assertEqual(420, parse_chf('CHF +4.2'))
self.assertEqual(420, parse_chf('+4.2'))
def test_parse_pad_right_negative(self): def test_parse_pad_right_negative(self):
self.assertEqual(-420, parse_chf('CHF -4.20')) self.assertEqual(-420, parse_chf('CHF -4.20'))
self.assertEqual(-420, parse_chf('-4.20')) self.assertEqual(-420, parse_chf('-4.20'))
@ -121,10 +172,14 @@ class TestCurrencyFormat(unittest.TestCase):
def test_parse_too_many_decimals(self): def test_parse_too_many_decimals(self):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
parse_chf('123.456') parse_chf('123.456')
with self.assertRaises(ValueError):
parse_chf('-123.456')
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
parse_chf('CHF 0.456') parse_chf('CHF 0.456')
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
parse_chf('CHF 0.450') parse_chf('CHF 0.450')
with self.assertRaises(ValueError):
parse_chf('CHF +0.456')
def test_parse_wrong_separator(self): def test_parse_wrong_separator(self):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
@ -137,3 +192,7 @@ class TestCurrencyFormat(unittest.TestCase):
parse_chf('13.-7') parse_chf('13.-7')
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
parse_chf('CHF 13.-7') parse_chf('CHF 13.-7')
with self.assertRaises(ValueError):
parse_chf('+13.-7')
with self.assertRaises(ValueError):
parse_chf('CHF -13.-7')