Fixed calc command.

This commit is contained in:
Jeremy Fincher 2003-09-07 20:29:42 +00:00
parent 4bb8d6a479
commit 66b62a42cd
2 changed files with 36 additions and 21 deletions

View File

@ -499,9 +499,13 @@ class FunCommands(callbacks.Privmsg):
_mathEnv = {'__builtins__': new.module('__builtins__'), 'i': 1j} _mathEnv = {'__builtins__': new.module('__builtins__'), 'i': 1j}
_mathEnv.update(math.__dict__) _mathEnv.update(math.__dict__)
_mathEnv.update(cmath.__dict__) _mathEnv.update(cmath.__dict__)
_mathInt = re.compile(r'(?<!\d|\.)(\d+)(?!\d+|\.|\.\d+)') _mathRe = re.compile(r'((?:(?<![A-Fa-f\d])-)?'
_mathHex = re.compile(r'(0x[A-Fa-f\d]+)') r'(?:0x[A-Fa-f\d]+|'
_mathOctal = re.compile(r'(^|[^\dA-Fa-f.])(0[0-7]+)') r'0[0-7]+|'
r'\d+\.\d+|'
r'\.\d+|'
r'\d+\.|'
r'\d+))')
def _complexToString(self, x): def _complexToString(self, x):
real = x.real real = x.real
imag = x.imag imag = x.imag
@ -517,10 +521,18 @@ class FunCommands(callbacks.Privmsg):
imag = 0 imag = 0
if imag == 0: if imag == 0:
return str(real) return str(real)
elif real == 0: elif imag == 1:
return '%s*i' % imag imag = 'i'
elif imag == -1:
imag = '-i'
elif imag < 0:
imag = '%si' % imag
elif imag > 0:
imag = '+%si' % imag
if real == 0:
return imag.lstrip('+')
else: else:
return '%s+%si' % (real, imag) return '%s%s' % (real, imag)
def calc(self, irc, msg, args): def calc(self, irc, msg, args):
"""<math expression> """<math expression>
@ -531,20 +543,19 @@ class FunCommands(callbacks.Privmsg):
text = privmsgs.getArgs(args) text = privmsgs.getArgs(args)
text = text.translate(string.ascii, '_[] \t') text = text.translate(string.ascii, '_[] \t')
text = text.replace('lambda', '') text = text.replace('lambda', '')
def hex2float(m): def handleMatch(m):
literal = m.group(1) s = m.group(1)
i = long(literal, 16) if s.startswith('0x'):
return '%s.0' % i i = int(s, 16)
def oct2float(m): elif s.startswith('0') and '.' not in s:
(previous, literal) = m.groups() try:
i = long(literal, 8) i = int(s, 8)
return '%s%s.0' % (previous, i) except ValueError:
text = self._mathHex.sub(hex2float, text) i = int(s)
#debug.printf('After unhexing: %r' % text) else:
text = self._mathOctal.sub(oct2float, text) i = float(s)
#debug.printf('After unocting: %r' % text) return str(complex(i))
text = self._mathInt.sub(r'\1.0', text) text = self._mathRe.sub(handleMatch, text)
#debug.printf('After uninting: %r' % text)
try: try:
x = complex(eval(text, self._mathEnv, self._mathEnv)) x = complex(eval(text, self._mathEnv, self._mathEnv))
irc.reply(msg, self._complexToString(x)) irc.reply(msg, self._complexToString(x))
@ -564,7 +575,7 @@ class FunCommands(callbacks.Privmsg):
stack = [] stack = []
for arg in args: for arg in args:
try: try:
stack.append(float(arg)) stack.append(complex(arg))
except ValueError: # Not a float. except ValueError: # Not a float.
if arg in self._mathEnv: if arg in self._mathEnv:
f = self._mathEnv[arg] f = self._mathEnv[arg]

View File

@ -57,6 +57,10 @@ class FunCommandsTest(PluginTestCase, PluginDocumentation):
def testCalc(self): def testCalc(self):
self.assertResponse('calc 5*0.06', str(5*0.06)) self.assertResponse('calc 5*0.06', str(5*0.06))
self.assertResponse('calc 2.0-7.0', str(2-7)) self.assertResponse('calc 2.0-7.0', str(2-7))
self.assertResponse('calc (-1)**.5', 'i')
self.assertResponse('calc e**(i*pi)+1', '0')
self.assertResponse('calc (-5)**.5', '2.2360679775i')
self.assertResponse('calc -((-5)**.5)', '-2.2360679775i')
def testChr(self): def testChr(self):
for i in range(256): for i in range(256):