""" Pi - calculate pi over time via the monte carlo method. idea borrowed from #linode Copyright (C) 2010 Brian S. Stephan This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ from ConfigParser import NoOptionError, NoSectionError import math import random from extlib import irclib from Module import Module class Pi(Module): """ Use the Monte Carlo method to approximate pi. Each time this method is called, it calculates a random point inside a square on the xy plane. If that point also falls within a circle bound within that square, it is added to the count of points inside. Over time, 4 * count_inside / count approaches pi. Idea from #linode on OFTC. Code from http://www.eveandersson.com/pi/monte-carlo-circle """ def do(self, connection, event, nick, userhost, replypath, what, admin_unlocked): if what == "pi": try: if not self.config.has_section(self.__class__.__name__): self.config.add_section(self.__class__.__name__) # set default values if unset if not self.config.has_option(self.__class__.__name__, "count_inside"): self.config.set(self.__class__.__name__, "count_inside", "0") if not self.config.has_option(self.__class__.__name__, "count"): self.config.set(self.__class__.__name__, "count", "0") # load values from config count_inside = self.config.getint(self.__class__.__name__, "count_inside") count = self.config.getint(self.__class__.__name__, "count") x = random.random() y = random.random() inside = False d = math.hypot(x,y) if d < 1: inside = True count_inside += 1 count += 1 pi = 4.0 * count_inside / count self.config.set(self.__class__.__name__, "count_inside", str(count_inside)) self.config.set(self.__class__.__name__, "count", str(count)) return self.reply(connection, replypath, "({0:.10f}, {1:.10f}) is {2}within the circle. pi is {5:.10f} ({3:d}/{4:d}).".format(x, y, "" if inside else "not ", count_inside, count, pi)); except NoOptionError, NoSectionError: pass # vi:tabstop=4:expandtab:autoindent # kate: indent-mode python;indent-width 4;replace-tabs on;