Code: Alles auswählen
#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import, division, print_function
import Tkinter as tk
from itertools import islice, izip
from math import sqrt
from random import random
from tkMessageBox import showerror
class Simulation(object):
def __init__(self):
random_values = iter(random, None)
self.random_coordinates = izip(random_values, random_values)
self.total_count = 0
self.hit_count = 0
def __iter__(self):
return self
def next(self):
result = x, y = next(self.random_coordinates)
self.total_count += 1
if sqrt(x**2 + y**2) <= 1:
self.hit_count += 1
return result
@property
def pi(self):
return 4 * (self.hit_count / self.total_count)
class SimulationUI(tk.Frame):
BATCH_SIZE = 1000
def __init__(self, master, canvas_size=500):
tk.Frame.__init__(self, master)
self.canvas_size = canvas_size
self.simulation = None
self.sample_count = None
self.canvas = tk.Canvas(
self,
height=self.canvas_size,
width=self.canvas_size,
background='green',
)
self.canvas.create_arc(
-self.canvas_size,
0,
self.canvas_size,
self.canvas_size * 2,
fill='blue',
outline='',
)
self.canvas.pack()
self.iteration_count_var = tk.IntVar(self, value=100000)
self.result_var = tk.StringVar(self, value='-')
frame = tk.Frame(self)
tk.Label(frame, text='# Iterations:').pack(side=tk.LEFT)
tk.Entry(
frame, textvariable=self.iteration_count_var
).pack(side=tk.LEFT)
self.start_button = tk.Button(
frame, text='Start', command=self.do_start
)
self.start_button.pack(side=tk.LEFT)
frame.pack()
tk.Label(self, textvariable=self.result_var).pack()
def plot(self, coordinate):
x, y = (c * self.canvas_size for c in coordinate)
self.canvas.create_line(x, y, x, y + 1, fill='red', tags='dot')
def do_start(self):
self.canvas.delete('dot')
try:
self.sample_count = self.iteration_count_var.get()
except ValueError:
showerror('No Number', 'Iteration count must be a number.')
else:
if self.sample_count < 1:
showerror('To Small', 'Iteration count has to be 1 or greater.')
else:
self.start_button['state'] = tk.DISABLED
self.simulation = Simulation()
self.run_simulation()
def run_simulation(self):
for coordinate in islice(
self.simulation, min(self.sample_count, self.BATCH_SIZE)
):
self.plot(coordinate)
self.sample_count = max(0, self.sample_count - self.BATCH_SIZE)
self.result_var.set(format(self.simulation.pi, '.20f'))
if self.sample_count:
self.after_idle(self.run_simulation)
else:
self.start_button['state'] = tk.NORMAL
def main():
root = tk.Tk()
root.title('Monte-Carlo Simulation for Pi')
simulation_ui = SimulationUI(root)
simulation_ui.pack()
root.mainloop()
if __name__ == '__main__':
main()