diff --git a/oxrlib/commands/historical.py b/oxrlib/commands/historical.py index 0e578874423938c75acec7ac5d4b00118b176e60..dc338cda3c75f3355b7d5975fd66ce3a4f5c9bee 100644 --- a/oxrlib/commands/historical.py +++ b/oxrlib/commands/historical.py @@ -43,17 +43,33 @@ class Formatter: return decimal.Decimal(amt_s) def normalize_rate(self, rate, prec=None): - return rate + if prec is None: + prec = self.rate_prec + _, digits, exponent = rate.normalize().as_tuple() + # Return ``prec`` nonzero digits of precision, if available. + prec -= min(0, exponent + len(digits)) + quant_to = '1.{}'.format('0' * prec) + try: + qrate = rate.quantize(decimal.Decimal(quant_to)) + except decimal.InvalidOperation: + # The original rate doesn't have that much precision, so use it raw. + qrate = rate + return qrate.normalize() - def format_rate(self, rate): - return "{:g}".format(rate) + def format_rate(self, rate, curr, fmt='{}', prec=None): + rate_s = self.format_currency( + self.normalize_rate(rate, prec), + curr, + currency_digits=False, + ) + return fmt.format(rate_s) def format_rate_pair(self, from_curr, to_curr): - from_amt = 1 + from_amt = decimal.Decimal(1) to_amt = self.cost_rates.convert(from_amt, from_curr, to_curr) - return "{} {} = {} {}".format( - self.format_rate(from_amt), from_curr, - self.format_rate(to_amt), to_curr, + return "{} = {}".format( + self.format_rate(from_amt, from_curr), + self.format_rate(to_amt, to_curr), ) def format_rate_pair_bidir(self, from_curr, to_curr, sep='\n'): @@ -81,28 +97,6 @@ class BeancountFormatter(Formatter): else: return self.price_rates.convert(from_amt, from_curr, to_curr) - def normalize_rate(self, rate, prec=None): - if prec is None: - prec = self.rate_prec - _, digits, exponent = rate.normalize().as_tuple() - # Return ``prec`` nonzero digits of precision, if available. - prec -= min(0, exponent + len(digits)) - quant_to = '1.{}'.format('0' * prec) - try: - qrate = rate.quantize(decimal.Decimal(quant_to)) - except decimal.InvalidOperation: - # The original rate doesn't have that much precision, so use it raw. - qrate = rate - return qrate.normalize() - - def _pretty_rate(self, fmt, rate, curr): - rate_s = self.format_currency( - self.normalize_rate(rate), - curr, - currency_digits=False, - ) - return fmt.format(rate_s) - def format_rate_pair(self, from_curr, to_curr): from_amt = 1 cost = self.cost_rates.convert(from_amt, from_curr, to_curr) @@ -110,11 +104,11 @@ class BeancountFormatter(Formatter): if price is None: price_s = '' else: - price_s = self._pretty_rate(self.PRICE_FMT, price, to_curr) + price_s = self.format_rate(price, to_curr, self.PRICE_FMT) return "{} {} {}{}".format( from_amt, from_curr, - self._pretty_rate(self.COST_FMT, cost, to_curr), + self.format_rate(cost, to_curr, self.COST_FMT), price_s, ) @@ -137,10 +131,10 @@ class BeancountFormatter(Formatter): if price is None: price_s = '' else: - price_s = self._pretty_rate(self.PRICE_FMT, price, denomination) + price_s = self.format_rate(price, denomination, self.PRICE_FMT) return "{} {}{}".format( amt_s, - self._pretty_rate(self.COST_FMT, cost, denomination), + self.format_rate(cost, denomination, self.COST_FMT), price_s, )