minetestbot-modules/calc.py

67 lines
2.0 KiB
Python
Raw Normal View History

2013-01-07 10:00:44 -08:00
#!/usr/bin/env python
# coding=utf-8
"""
calc.py - Phenny Calculator Module
2014-01-06 07:01:54 -08:00
Copyright 2014, sfan5
2013-01-07 10:00:44 -08:00
"""
2014-01-06 07:01:54 -08:00
import ast
import operator as op
import math
# http://stackoverflow.com/questions/2371436/evaluating-a-mathematical-expression-in-a-string/9558001#9558001
operators = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, ast.Pow: op.pow,
ast.Div: op.truediv, ast.BitXor: op.xor, ast.Mod: op.mod}
2014-01-06 07:27:57 -08:00
funcs = {"bin": bin, "abs": abs, "oct": oct, "int": int, "sum": sum}
2014-01-06 07:01:54 -08:00
for funcn in dir(math):
if funcn.startswith("__"):
continue
funcs[funcn] = getattr(math, funcn)
def getfunc(fn):
if fn in funcs:
return funcs[fn]
else:
raise ValueError("Function not allowed: '" + str(fn) + "'")
def eval_expr(expr):
return eval_(ast.parse(expr).body[0].value) # Module(body=[Expr(value=...)])
def eval_(node):
if isinstance(node, ast.Num): # <number>
return node.n
elif isinstance(node, ast.operator): # <operator>
return operators[type(node)]
elif isinstance(node, ast.BinOp): # <left> <operator> <right>
return eval_(node.op)(eval_(node.left), eval_(node.right))
elif isinstance(node, ast.Call): # <func> ( <args> )
2014-01-06 07:10:13 -08:00
return getfunc(node.func.id)(*(eval_(e) for e in node.args))
2014-01-06 07:27:57 -08:00
elif isinstance(node, ast.Tuple): # ( <arg> , <arg2> , [...] )
2014-01-06 07:24:10 -08:00
return tuple(eval_(e) for e in node.elts)
2014-01-06 07:27:57 -08:00
elif isinstance(node, ast.List): # [ <arg> , <arg2> , [...] ]
2014-01-06 07:24:10 -08:00
return list(eval_(e) for e in node.elts)
2014-01-06 07:01:54 -08:00
else:
raise TypeError("AST node type not allowed: '" + type(node).__name__ + "'")
def c(phenny, input):
for x in phenny.bot.commands["high"].values():
if x[0].__name__ == "aa_hook":
if x[0](phenny, input):
return # Abort function
if not input.group(2):
return phenny.reply("Nothing to calculate.")
q = input.group(2).encode('utf-8')
print("[LOG]: %s calculated '%s'" % (input.nick,q))
try:
2014-01-06 07:24:10 -08:00
phenny.say(repr(eval_expr(q)))
2014-01-06 07:10:13 -08:00
except Exception as e:
phenny.say("Exception: " + str(e))
2014-01-06 07:01:54 -08:00
2013-01-07 10:00:44 -08:00
c.commands = ['c']
c.example = '.c 5 + 3'
if __name__ == '__main__':
2014-01-06 07:10:13 -08:00
print __doc__.strip()