#!/usr/bin/env python
import math, re

parser = re.compile('integrate (.*) from ([0-9]+\.?[0-9]*) to ([0-9]+\.?[0-9]*)( )?(step)? ([0-9]+\.?[0-9]*)?')

safeFuncs = {
	'acos' : math.acos,
	'asin' : math.asin,
	'atan' : math.atan,
	'atan2' : math.atan2,
	'ceil' : math.ceil,
	'cos' : math.cos,
	'e' : math.e,
	'exp' : math.exp,
	'floor' : math.floor,
	'log' : math.log,
	'log10' : math.log10,
	'pi' : math.pi,
	'pow' : math.pow,
	'sin' : math.sin,
	'sqrt' : math.sqrt,
	'tan' : math.tan
}

minimumStepSize = 0.0001

def runStringIntegral(f, a, b, step=0.1):
	s = 0
	i = a
	sandbox = { t:safeFuncs[t] for t in safeFuncs.keys()}

	if step == 0:
		sandbox["x"] = a
		return eval(f, {"__builtins__":None}, sandbox)

	while i < b:
		sandbox["x"] = i
		s = s + eval(f, {"__builtins__":None}, sandbox)
		i += step
	s /= (1.0 / step)
	return s

def parseAndRunInteg(message):
	data = parser.match(message)
	if not data == None:
		formula, a, b, _, _, step = data.groups()
		if step == None:
			step = 0.1

		if float(step) < minimumStepSize:
			print "Sorry, I dont do integrations with stepsize < %s" % minimumStepSize
			return None

		#print "Calculating %s from %s to %s with step %s" %(formula, a, b, step)
		print "The result of %s is: %s" %(message, runStringIntegral(formula, float(a), float(b), float(step)))
	else:
		print "Sorry I did not understand"

'''
	Tests
'''
#parseAndRunInteg("integrate sin(x) from 0 to 3.14 step 0.1") # Should be near 2
#parseAndRunInteg("integrate sin(x) * pi from 0 to 3.14 step 0.1") # Should be near 6.28
#parseAndRunInteg("integrate x ** 2 from 0 to 10 step 0.001") # Should be near 333
#parseAndRunInteg("integrate x ** 2 from 1 to 4 step 0.000001") # Should print error
