Science
In reply to the discussion: The Joys of Being Wrong, the diligence of DUer "SunSeeker", and the Elimination of the Penny [View all]Bernardo de La Paz
(59,897 posts)from math import floor
from random import random
import sys
version = "v0.3"
print (f'TransactRound {version}')
print (f'python {sys.version [0: 7]}n')
prices = []
price_counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]  # 10 tails
coi = [0, 0, 0, 0, 0]
diffs_count = [0, 0, 0, 0, 0]
total_diffs = 0
sim_num = 0
numbers_of_items = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5]
def price_range (tail, count) :
    for _ in range (count):
        price = rand_price (tail)
        prices.append (price)
        price_counts [tail] += 1
def rand_price (tail:int) -> float:
    while True:
        price = floor (random () * 99) * 10 + tail
        if price >= 20:
            return price
def print_results (num:int) :
    print (f'nCount {num: 9, } :',
           f'1 item: {100*(coi[0]/num):4.1f}%,  ',
           f'2: {100*(coi[1]/num):4.1f}%,  ',
           f'3: {100*(coi[2]/num):4.1f}%,  ',
           f'4: {100*(coi[3]/num):4.1f}%,  ',
           f'5: {100*(coi[4]/num):4.1f}%.')
    print (f'Diffs counts:  -2:{(diffs_count [0]/num)*100:5.1f} %,  ',
           f'-1:{(diffs_count [1]/num)*100:5.1f} %,  ',
           f'0:{(diffs_count [2]/num)*100:5.1f} %,  ',
           f'1:{(diffs_count [3]/num)*100:5.1f} %,  ',
           f'2:{(diffs_count [4]/num)*100:5.1f} %.')
    print (f'Total_diffs {total_diffs:,}:',
           f' per transaction: {total_diffs / num:5.3f} cents.')
def simulate (count:int, title:str, tax_percent:float=0.0, pr_sample:bool=False ):
    '''
    tax_rate 0.0 is silent.
    tax_rate < 0.0 means use random tax rates
    '''
    global coi, diffs_count
    coi = [0, 0, 0, 0, 0]
    diffs_count = [0, 0, 0, 0, 0]
    if tax_percent == 0.0:
        taxing:bool = False
    else:
        taxing:bool = True
        if tax_percent < 0.0:
            tax_rate_random = True
        else:
            tax_rate = tax_percent / 100
            tax_rate_random = False
    global sim_num
    sim_num += 1
    title = f'Simulation {sim_num}:  {title}'
    if taxing:
        if tax_rate_random:
            title += ' with random tax rates'
        else:
            title += f' with tax rate {tax_percent} %'
    print (f'nn{title}n')
    if pr_sample or ((sim_num % 4) == 1):
        out = f'Percent last digit:n'
        for i in range (10):
            out += f'{i}: {price_counts /40:4.1f} %n'
        print (out)
    diff_round = [0, -1, -2, 2, 1]
    if pr_sample:
        print ('First 20 transactions:n')
    item_str = ''
    global total_diffs
    total_diffs = 0
    for i in range (count):
        num_items = numbers_of_items [int (random () * 20)]
        coi [num_items - 1] += 1
        total = 0
        for j in range (num_items):
            index = floor (random () * 3998.9)
            item = prices [index]
            if i < 20:
                item_str += f' {item/100:5.2f}'
            total += item
        if taxing:
            if tax_rate_random:
                tax_rate = 0.0025 * int (46 * random ())
            tax = round (total * tax_rate)
            total_w_tax = total + tax
            tax_str = f' tax rate {tax_rate*100:4.1f}%,'
            tax_str += f' tax {tax/100:5.2f}, total w tax {total_w_tax/100:5.2f},'
        else:
            total_w_tax = total
            tax_str = ""
        digit = total_w_tax % 5
        diff = diff_round [digit]
        diffs_count [2 + diff] += 1
        cash = total_w_tax + diff
        total_diffs += diff
        if pr_sample and (i < 20):
            out = f'items {num_items}:  '
            out += f' total {total/100:5.2f},'
            out += tax_str
            out += f' diff {diff:2},'
            out += f' cash {cash/100:5.2f}:'
            out += f' {item_str}'
            print (f'{(i+1):2}:  {out}')
            item_str = ''
            condition = False
        else:
            condition = (i == count / 1000) or (i == count / 100) or 
                        (i == count / 10)
        if condition:
            print_results (i)
    print_results (count)
    print (f'nEnd of {title}.')
count = 20 * 1000 * 1000
count = 200 * 1000
prices = []
price_counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]  # 10 tails
price_range (0, 400)
price_range (5, 3600)
print ('Simulation of Rounding on large numbers of Transactions')
print ('   by a method like Lombra, Easter Economic Journal, v27n4, Fall 2001n')
print (f'Size of prices {len (prices)}')
simulate (count, "Prices rounded to 0 or 5 cents" )
simulate (count, "Prices rounded to 0 or 5 cents", 5.0)
simulate (count, "Prices rounded to 0 or 5 cents", 11.25)
simulate (count, "Prices rounded to 0 or 5 cents", -99)
prices = []
price_counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]  # 10 tails
price_range (0, 400); price_range (1, 400); price_range (2, 400);
price_range (3, 400); price_range (4, 400); price_range (5, 400);
price_range (6, 400); price_range (7, 400); price_range (8, 400);
price_range (9, 400)
simulate (count, "Prices random tails" )
simulate (count, "Prices random tails", 5.0)
simulate (count, "Prices random tails", 11.25)
simulate (count, "Prices random tails", -99)
prices = []
price_counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]  # 10 tails
# 4 * percent * 10.  Lombra data.
price_range (0, 4 * 2); price_range (1, 4 * 1); price_range (2, 4 * 2)
price_range (3, 4 * 5); price_range (4, 4 * 90); price_range (5, 4 * 37)
price_range (6, 4 * 29); price_range (7, 4 * 1); price_range (8, 4 * 8)
price_range (9, 4 * 825)
simulate (count, "Lombra distribution of prices", 0.0, True)
simulate (count, "Lombra distribution of prices", 5.0)
simulate (count, "Lombra distribution of prices", 11.25, True)
simulate (count, "Lombra distribution of prices", -99)
prices = []
price_counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]  # 10 tails
price_range (9, 4 * 800)
price_range (8, 4 * 80)
price_range (5, 4 * 60)
price_range (4, 4 * 20)
price_range (7, 4 * 20)
price_range (0, 4 * 16)
price_range (1, 4 * 1)
price_range (2, 4 * 1)
price_range (3, 4 * 1)
price_range (6, 4 * 1)
simulate (count, "Imagined distribution of prices", 0.0, True)
simulate (count, "Imagined distribution of prices", 5.0)
simulate (count, "Imagined distribution of prices", 11.25)
simulate (count, "Imagined distribution of prices", -99)
print ('nFini.')
Edit history
Recommendations
1 members have recommended this reply (displayed in chronological order): = new reply since forum marked as read
							
						
      
      
					
						Highlight:
						NoneDon't highlight anything
						5 newestHighlight 5 most recent replies
						RecommendedHighlight replies with 5 or more recommendations
 = new reply since forum marked as read
							
						
      
      
					
						Highlight:
						NoneDon't highlight anything
						5 newestHighlight 5 most recent replies
						RecommendedHighlight replies with 5 or more recommendations
					
                    
					