2010-10-18 22:48:51 -05:00
"""
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 < http : / / www . gnu . org / licenses / > .
"""
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 ) )
2010-10-20 11:57:31 -05:00
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 ) ) ;
2010-10-18 22:48:51 -05:00
except NoOptionError , NoSectionError : pass
# vi:tabstop=4:expandtab:autoindent
# kate: indent-mode python;indent-width 4;replace-tabs on;