From b34e07ba21e1fe85db782d52b286d43d37cb38cc Mon Sep 17 00:00:00 2001 From: Paul Walko Date: Thu, 20 Jun 2019 21:45:18 -0400 Subject: [PATCH] Use newton api instead of google calc regex --- modules/calc.py | 42 +++++++---------- modules/search.py | 9 ++++ modules/test/test_calc.py | 98 +++++++++++++++++++++++++++++++++------ 3 files changed, 110 insertions(+), 39 deletions(-) diff --git a/modules/calc.py b/modules/calc.py index 0328d2c..4a9bdc4 100644 --- a/modules/calc.py +++ b/modules/calc.py @@ -10,44 +10,34 @@ http://inamidst.com/phenny/ import re import web -from modules.search import generic_google +from modules.search import newton_api -subs = [ - ('£', 'GBP '), - ('€', 'EUR '), - ('\$', 'USD '), - (r'\n', '; '), - ('°', '°'), - (r'\/', '/'), -] - -r_google_calc = re.compile(r'calculator-40.gif.*? = (.*?)<') -r_google_calc_exp = re.compile(r'calculator-40.gif.*? = (.*?)(.*?)') +operations = {'simplify', 'factor', 'derive', 'integrate', 'zeroes', 'tangent', + 'area', 'cos', 'sin', 'tan', 'arccos', 'arcsin', 'arctan', 'abs', 'log'} def c(phenny, input): - """Google calculator.""" + """Newton calculator.""" if not input.group(2): return phenny.reply("Nothing to calculate.") q = input.group(2) - bytes = generic_google(q) - m = r_google_calc_exp.search(bytes) - if not m: - m = r_google_calc.search(bytes) + q = q.split(' ', 1) - if not m: - num = None - elif m.lastindex == 1: - num = web.decode(m.group(1)) - else: - num = "^".join((web.decode(m.group(1)), web.decode(m.group(2)))) + if len(q) > 1 and q[0] in operations: + operation = q[0] + expression = q[1] + elif len(q) > 0: + operation = 'simplify' + expression = q[0] - if num: - num = num.replace('×', '*') - phenny.say(num) + result = newton_api(operation, expression) + + if result: + phenny.say(result) else: phenny.reply("Sorry, no result.") c.commands = ['c'] c.example = '.c 5 + 3' +c.example = '.c integrate 1/3 x^3 + x^2 + C' if __name__ == '__main__': diff --git a/modules/search.py b/modules/search.py index 43b3ad2..7ae6c19 100644 --- a/modules/search.py +++ b/modules/search.py @@ -162,6 +162,15 @@ def duck(phenny, input): duck.commands = ['duck', 'ddg'] duck.example = '.duck football' +def newton_api(operation, expression): + expression = web.quote(expression, safe='') + uri = "https://newton.now.sh/{}/{}".format(operation, expression) + bytes = web.get(uri) + json = web.json(bytes) + if 'result' in json: + return str(json['result']) + return None + def search(phenny, input): if not input.group(2): return phenny.reply('.search for what?') diff --git a/modules/test/test_calc.py b/modules/test/test_calc.py index 4a405be..fca3d91 100644 --- a/modules/test/test_calc.py +++ b/modules/test/test_calc.py @@ -19,26 +19,98 @@ class TestCalc(unittest.TestCase): self.phenny.say.assert_called_once_with('25') - def test_c_sqrt(self): - input = Mock(group=lambda x: '4^(1/2)') + def test_c_simplify(self): + input = Mock(group=lambda x: 'simplify 2^2+2(2)') c(self.phenny, input) - self.phenny.say.assert_called_once_with('2') + self.phenny.say.assert_called_once_with('8') - def test_c_scientific(self): - input = Mock(group=lambda x: '2^64') + def test_c_factor(self): + input = Mock(group=lambda x: 'factor x^2 + 2x') c(self.phenny, input) - self.phenny.say.assert_called_once_with('1.84467441 * 10^19') + self.phenny.say.assert_called_once_with('x (x + 2)') + + def test_c_derive(self): + input = Mock(group=lambda x: 'derive x^2+2x') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('2 x + 2') + + def test_c_integrate(self): + input = Mock(group=lambda x: 'integrate x^2+2x') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('1/3 x^3 + x^2') + + def test_c_zeroes(self): + input = Mock(group=lambda x: 'zeroes x^2+2x') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('[-2, 0]') + + def test_c_tangent(self): + input = Mock(group=lambda x: 'tangent 2|x^3') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('12 x + -16') + + def test_c_area(self): + input = Mock(group=lambda x: 'area 2:4|x^3') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('60') + + def test_c_cos(self): + input = Mock(group=lambda x: 'cos pi') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('-1') + + def test_c_sin(self): + input = Mock(group=lambda x: 'sin 0') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('0') + + def test_c_tan(self): + input = Mock(group=lambda x: 'tan .03') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('0.030009') + + def test_c_arccos(self): + input = Mock(group=lambda x: 'arccos 1') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('0') + + def test_c_arcsin(self): + input = Mock(group=lambda x: 'arcsin .04') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('0.0400107') + + def test_c_arctan(self): + input = Mock(group=lambda x: 'arctan 1') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('1/2 pi') + + def test_c_abs(self): + input = Mock(group=lambda x: 'abs -3') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('3') + + def test_c_log(self): + input = Mock(group=lambda x: 'log 2|8') + c(self.phenny, input) + + self.phenny.say.assert_called_once_with('3') def test_c_none(self): - input = Mock(group=lambda x: 'aif') + input = Mock(group=lambda x: 'tangent 2lx^3') c(self.phenny, input) self.phenny.reply.assert_called_once_with('Sorry, no result.') - - def test_c_quirk(self): - input = Mock(group=lambda x: '24/50') - c(self.phenny, input) - - self.phenny.say.assert_called_once_with('0.48')