def main(): parser = argparse.ArgumentParser(description=__doc__.strip()) parser.add_argument('filename', help='Filenames') args = parser.parse_args() entries, errors, options_map = loader.load_file(args.filename) # Gather all the price directives. prices_map = collections.defaultdict(list) for entry in entries: if not isinstance(entry, data.Price): continue # Ignore automatically calculated prices. if '__implicit_prices__' in entry.meta: continue base_quote = (entry.currency, entry.amount.currency) prices_map[base_quote].append((entry.meta, entry.amount.number)) # Read all the input file contents. filenames = { meta["filename"] for base_quote, meta_number_list in prices_map.items() for meta, _ in meta_number_list } filemap = { filename: open(filename).readlines() for filename in sorted(filenames) } # Infer the right quantization and quantize the price numbers. ten = Decimal("10") max_digits = 5 for base_quote, meta_number_list in prices_map.items(): prices_list = [price for _, price in meta_number_list] exponent = number.infer_quantum_from_list(prices_list) exponent = max(exponent, -max_digits) qua = ten**exponent for meta, price in meta_number_list: filename = meta["filename"] lineno = meta["lineno"] - 1 qprice = price.quantize(qua) qtuple = qprice.as_tuple() if (qtuple.exponent < price.as_tuple().exponent or -qtuple.exponent == 0): continue newline = re.sub(str(price), str(qprice), filemap[filename][lineno]) filemap[filename][lineno] = newline # Reformat price lines. for filename, lines in filemap.items(): lines[:] = [price_reformat(line) for line in lines] # Write out modified files. for filename, lines in filemap.items(): with open(filename + ".fixed", "w") as outfile: for line in lines: outfile.write(line)
def test_infer_quantization_normal(self): for exp, expected_qua in [(2, D("0.01")), (3, D("0.001")), (5, D("0.00001"))]: xn = [ Decimal((ix + fx / 1000) / (10**exp)) for ix, fx in zip(self.ir, self.fr) ] exp = number.infer_quantum_from_list(xn) self.assertEqual(expected_qua, number.TEN**exp)
def test_infer_quantization_under3(self): prices = [ Decimal('0.7728273890026662544920591986'), Decimal('0.8199409642505739586749754018'), Decimal('0.7812805187702644634556037345'), Decimal('0.776343267939352063908577816800'), Decimal('0.782074844562624603847313364900') ] exp = number.infer_quantum_from_list(prices)
def test_infer_quantization_none(self): with decimal.localcontext() as ctx: ctx.prec = 20 # Note: All the instances are actually floats, so larger prec. numbers = list( map(Decimal, [ 0.8462362724718449, 0.7053497034927213, 0.18865925698056718, 0.4231422803809822, 0.1454769973533604, 0.11586558849935513, 0.04047872493132432, 0.09511048123106225, 0.4932086961083296, 0.12377443905156471 ])) exp = number.infer_quantum_from_list(numbers) self.assertEqual(-21, exp)
def test_infer_quantization_under(self): prices = list( map(Decimal, [ '0.033255736614566012637179913540', '0.033232527998404838656076567740', '0.033316674995835415625520573050', '0.033940874995757390625530326170', '0.034093621083495278033479935900', '0.033997416196369075950227782690', '0.034020548411240389195073824590', '0.034090134315129201609054339670', '0.034700534388229578735512526890', '0.034191541012753444797757034910', '0.034984606773019871256647075290' ])) exp = number.infer_quantum_from_list(prices) self.assertEqual(Decimal("1e-29"), number.TEN**exp)
def test_infer_quantization_one(self): xn = [Decimal(ix + fx / 1000) for ix, fx in zip(self.ir, self.fr)] qua = number.infer_quantum_from_list(xn) self.assertEqual(0, qua)