# Monte Carlo method of computing pi # Toss darts at a dart board (2x2, centered at (0,0) # The ratio of the darts in the unit circle to all darts is pi/4 # import random import math # Generate a landing position for a dart tossed at # a 2x2 square with center at (0,0) # returns: (x, y) co-ordinates of toss def gentoss(): x = 2*random.random() - 1 y = 2*random.random() - 1 return x, y # for point x, y, if x^2 + y^2 <= 1, they are in the unit circle # parameters: x, y: co-ordinates of point # returns True if so, False if not def inunitcircle(x, y): return x ** 2 + y ** 2 <= 1 # function to read and vet user selection # returns: n, the number of tosses # NOTE: n must be positive; return -1 to quit def getinput(): # loop until we get good input while True: try: # get the input and check the type here n = int(input("number of tosses (EOF to quit): ")) except EOFError: # user wants to quit, so help n = -1 break except ValueError: # user didn't enter a number print("You have to enter a positive n or EOF") continue # got an integer # now check the value we read/were given if n > 0: break # this is bad input, so say so print("You have to enter a positive n or EOF") # it's positve to continue, -1 to quit return n # main routine: pull it all together def main(): # get number of tosses n = getinput() if n > 0: # number of darts in unit circle # nothing thrown yet h = 0 # now start throwing for i in range(n): # toss x, y = gentoss() # is it in the circle? if inunitcircle(x, y): h += 1 # done! see how well you did ... print(" number of throws: %8d\t\tapproximation to pi: %9.7f" % (n, 4.0 * h / n)) print(" number of hits: %8d\t\t actual value of pi: %9.7f" % (h, math.pi)) print(" ratio: %8.6f\t\t error: %9.7f" % (h/n, abs(4.0 * h / n - math.pi))) # # run the simulation # main()