Advertisement
lardfat

coupons

Nov 8th, 2015
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.96 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. # Coupon Simulator 2015
  4. # let's calculamate perbability! Simulates the "balls in boxes"
  5. # problem with 50 boxes: how many throws, on average, until each box has at
  6. # least 1 ball in it? Another form of the "coupon collector's problem".
  7. # usage: coupons.py <# of trials> <-y> (to skip interactive approval of > 2500 trials)
  8. # - lardlung
  9.  
  10. import random
  11. import sys
  12. import argparse
  13. import math
  14.  
  15. results = list()
  16.  
  17. parser = argparse.ArgumentParser(description = "coupons.py: a probability simulator of the coupon collector's dilemma, or, balls and boxes.")
  18. parser.add_argument("trialcount", help = "<#> number of trials to run", type = int)
  19. parser.add_argument("-y", "--yes", action = 'store_true', help = "optional; skip interactive approval of trialcount > 2500")
  20. parser.add_argument("-b","--bins", help = "optional; number of boxes/bins to use. Default is 50", default = 50, action='store')
  21.  
  22.  
  23.  
  24. # do one trial.
  25.  
  26. def one_run(bins):
  27.  
  28.     myBins     = list()
  29.     throwCount = 0
  30.     poop       = 1
  31.  
  32.     for i in range(0,bins):
  33.         myBins.insert(i,0)
  34.  
  35.     while poop == 1:
  36.  
  37.         myThrow     = random.randint(0, bins - 1)
  38.         myBins[myThrow] = myBins[myThrow] + 1
  39.         throwCount  = throwCount + 1
  40.  
  41.         if 0 not in myBins:
  42.             poop = 2
  43.             return throwCount
  44.         else:
  45.             continue
  46.            
  47. # average results of multiple trials.
  48.  
  49. def do_results(trialCount):
  50.  
  51.     for i in range( 0, trialCount ):
  52.         results.insert(i,0)
  53.         results[i] = int(one_run(bins))
  54.  
  55.     trialsAverage = sum( results ) / float(trialCount)
  56.     return trialsAverage
  57.  
  58. # find a mathematical approximation of what the results should be.
  59. # em_gamma is an approximation of the euler-mascheroni constant!
  60. # http://mathworld.wolfram.com/Euler-MascheroniConstantApproximations.html
  61.  
  62. def do_calc(bins):
  63.  
  64.     em_gamma = math.pi/(2*math.e)
  65.     calcResult = bins * ( em_gamma + math.log(bins) )
  66.     return calcResult
  67.  
  68. # calculate the percent difference between the approximation and the trial results.
  69.  
  70. def do_percent(calcResults,avgResults):
  71.     x = ( abs(calcResults - avgResults) ) / ((calcResults + avgResults)/2)
  72.     pDiff = 100 * float(x)
  73.     return pDiff
  74.  
  75.  
  76. # go main loop, go!
  77.  
  78. try:
  79.     args = parser.parse_args()
  80.     trialCount = args.trialcount
  81.  
  82.     if args.bins == False:
  83.         bins = 50
  84.     else:
  85.         bins = int(args.bins)
  86.  
  87.     if trialCount >= 1 and trialCount <= 2500:
  88.  
  89.         avgResults = do_results(trialCount)
  90.         calcResults = do_calc(bins)
  91.         pDiff = do_percent(avgResults,calcResults)
  92.        
  93.         print "trials:", trialCount, "bins:", bins
  94.         print "expected result(calculated): {0:.3f}".format(calcResults)
  95.         print "averaged result:", avgResults
  96.         print "percent difference: {0:.3f}%".format(pDiff)
  97.  
  98.     elif trialCount > 2500:
  99.  
  100.         if not args.yes:
  101.             verify = raw_input("Are you SURE? y/n ")
  102.  
  103.            
  104.             if verify in ('Y','y'):
  105.  
  106.                 avgResults = do_results(trialCount)
  107.                         calcResults = do_calc(bins)
  108.                         pDiff = do_percent(avgResults,calcResults)
  109.  
  110.                         print "trials:", trialCount, "bins:", bins
  111.                         print "expected result(calculated): {0:.3f}".format(calcResults)
  112.                         print "averaged result:", avgResults
  113.                         print "percent difference: {0:.3f}%".format(pDiff)
  114.  
  115.    
  116.             elif verify in ('N','n'):
  117.                 print "aborted, but have 1 quick trial anyways:", one_run(bins)
  118.                 sys.exit(0)
  119.    
  120.             else:
  121.                 print "invalid input: aborted."
  122.                 sys.exit(0)
  123.  
  124.         elif args.yes:
  125.  
  126.             avgResults = do_results(trialCount)
  127.                 calcResults = do_calc(bins)
  128.                 pDiff = do_percent(avgResults,calcResults)
  129.  
  130.                     print "trials:", trialCount, "bins:", bins
  131.                 print "expected result(calculated): {0:.3f}".format(calcResults)
  132.                     print "averaged result:", avgResults
  133.                     print "percent difference: {0:.3f}%".format(pDiff)
  134.  
  135.        
  136.         else:
  137.             print "Usage: coupons.py <# of trials> <-y> (to skip interactive approval of > 2500 trials)"
  138.             sys.exit(1)
  139.    
  140.    
  141.     else:
  142.         print "bombElse", results
  143.  
  144.  
  145. except:
  146.     print "bombExcept"
  147.     sys.exit(0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement