From c3270ef3df70347629ad7d7519464e0d429a5ad9 Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Mon, 18 Oct 2010 22:48:51 -0500 Subject: [PATCH] module to calculate pi over time, via the monte carlo method. idea pinched from #linode. --- modules/Pi.py | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 modules/Pi.py diff --git a/modules/Pi.py b/modules/Pi.py new file mode 100644 index 0000000..8d89471 --- /dev/null +++ b/modules/Pi.py @@ -0,0 +1,70 @@ +""" +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;