Advertisement
here2share

# Tk_monte_carlo_pi.py

Oct 20th, 2020
753
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.46 KB | None | 0 0
  1. # Tk_monte_carlo_pi.py
  2.  
  3. #!/usr/bin/env python3
  4.  
  5. # How this works:
  6. #   Area of the circle = πr²
  7. #   Area of bounding box = (2r)²
  8. #
  9. # We know that the chance of selecting inside the circle (P) is area of
  10. # circle / area of bounding box
  11. #   P = (πr²) / (2r)²
  12. #
  13. # We can calculate P by putting a bunch of points into the box and seeing
  14. # how many are inside of the circle. H is hits, T is tries.
  15. #   P = H / T
  16. #
  17. # Now let's move some numbers around
  18. #   P = (πr²) / (2r)²
  19. #   H / T = (πr²) / (2r)²             <- P = H / T
  20. #   H / T = πr² / 4r²                 <- (2r)² = 4r²
  21. #   H / T = π / 4                   <- r² cancels out
  22. #   4 * H / T = π                   <- Multiply both sides by 4
  23. #   π = 4 * H / T                   <- Flip the sides
  24.  
  25. import math
  26. import random
  27. import tkinter as tk
  28.  
  29. INTERVAL = 1
  30. DOT_RADIUS = 2
  31. RADIUS = 300
  32. BORDER = 5
  33. CENTER = BORDER + RADIUS
  34. MAX_TRIES = 1000000
  35.  
  36.  
  37. class Application(tk.Frame):
  38.     def __init__(self, master=None):
  39.         super().__init__(master)
  40.         self.grid()
  41.         self.create_widgets()
  42.         self.hits = 0
  43.         self.tries = 0
  44.  
  45.     def create_widgets(self):
  46.         self.pi_label_text = tk.StringVar()
  47.         self.pi_label_text.set('π = ?')
  48.         self.pi_label = tk.Label(self, textvariable=self.pi_label_text)
  49.         self.pi_label.grid(row=1)
  50.         pi = '{:.6f}'.format(math.pi)
  51.         self.pi_label_text2 = tk.StringVar()
  52.         self.pi_label_text2.set(pi)
  53.         self.pi_label2 = tk.Label(self, textvariable=self.pi_label_text2)
  54.         self.pi_label2.grid(row=2)
  55.  
  56.         self.canv = tk.Canvas(
  57.             self,
  58.             width=(BORDER * 2 + RADIUS * 2),
  59.             height=(BORDER * 2 + RADIUS * 2))
  60.         self.canv.grid(row=3)
  61.         self.canv.create_oval(
  62.             BORDER, BORDER, BORDER + RADIUS * 2, BORDER + RADIUS * 2)
  63.         self.after(INTERVAL, self.add_dots)
  64.  
  65.     def rand_x_y(self):
  66.         x = random.randint(BORDER, BORDER + RADIUS * 2)
  67.         y = random.randint(BORDER, BORDER + RADIUS * 2)
  68.         return x, y
  69.  
  70.     def in_circle(self, x, y):
  71.         return math.sqrt((x - CENTER) ** 2 + (y - CENTER) ** 2) <= RADIUS
  72.  
  73.     def add_dots(self):
  74.         if self.tries >= MAX_TRIES:
  75.             return
  76.  
  77.         x, y = self.rand_x_y()
  78.  
  79.         if self.in_circle(x, y):
  80.             self.hits += 1
  81.             color = "#0f0"
  82.         else:
  83.             color = "#f00"
  84.         self.tries += 1
  85.  
  86.         self.canv.create_oval(
  87.             x - DOT_RADIUS, y - DOT_RADIUS,
  88.             x + DOT_RADIUS, y + DOT_RADIUS,
  89.             fill=color, outline=color)
  90.  
  91.         pi_guess = 4 * float(self.hits) / (self.tries)
  92.         self.pi_label_text.set('{:.6f}'.format(pi_guess))
  93.  
  94.         self.after(INTERVAL, self.add_dots)
  95.  
  96.  
  97. root = tk.Tk()
  98. app = Application(master=root)
  99. app.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement