Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New math operations #449

Merged
merged 3 commits into from
Dec 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 33 additions & 17 deletions chatterbot/logic/mathematical_evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
import json
import decimal
import numpy


class MathematicalEvaluation(LogicAdapter):
Expand All @@ -21,6 +22,7 @@ class MathematicalEvaluation(LogicAdapter):
4) Simplify the equation
5) Solve the equation & return result
"""
functions = ['log', 'sqrt']

def __init__(self, **kwargs):
super(MathematicalEvaluation, self).__init__(**kwargs)
Expand Down Expand Up @@ -72,7 +74,7 @@ def process(self, statement):

# Returning important information
try:
expression += "= " + str(eval(expression))
expression += "= " + str(eval(expression, {f: getattr(numpy, f) for f in self.functions}))

# return a confidence of 1 if the expression could be evaluated
return 1, Statement(expression)
Expand All @@ -84,23 +86,16 @@ def simplify_chunks(self, input_text):
Separates the incoming text.
"""
string = ''
chunks = re.split(r"([\w\.-]+|[\(\)\*\+])", input_text)
chunks = [chunk.strip() for chunk in chunks]
chunks = [chunk for chunk in chunks if chunk != '']

for chunk in input_text.split():

is_chunk_integer = self.is_integer(chunk)

if is_chunk_integer is False:
is_chunk_float = self.is_float(chunk)

if is_chunk_float is False:
is_chunk_operator = self.is_operator(chunk)

if is_chunk_operator is not False:
string += str(is_chunk_operator) + ' '
else:
string += str(is_chunk_float) + ' '
else:
string += str(is_chunk_integer) + ' '
for chunk in chunks:
for checker in ['is_integer', 'is_float', 'is_operator', 'is_constant', 'is_function']:
result = getattr(self, checker)(chunk)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really nice revision to the previous setup.

if result is not False:
string += str(result) + ' '
break

return string

Expand All @@ -126,6 +121,27 @@ def is_integer(self, string):
except:
return False

def is_constant(self, string):
"""
If the string is a mathematical constant, returns
said constant. Otherwise, it returns False.
"""
constants = {
"pi": 3.141693,
"e": 2.718281
}
return constants.get(string, False)

def is_function(self, string):
"""
If the string is an availbale mathematical function, returns
said function. Otherwise, it returns False.
"""
if string in self.functions:
return string
else:
return False

def is_operator(self, string):
"""
If the string is an operator, returns
Expand Down
11 changes: 11 additions & 0 deletions tests/logic_adapter_tests/test_mathematical_evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,14 @@ def test_negative_decimal_multiplication(self):
statement = Statement('What is -100.5 * 20?')
confidence, response = self.adapter.process(statement)
self.assertEqual(response.text, '( -100.5 * 20 ) = -2010.0')

def test_constants(self):
statement = Statement('What is pi plus e ?')
confidence, response = self.adapter.process(statement)
self.assertEqual(response.text, '3.141693 + 2.718281 = 5.859974')

def test_math_functions(self):
statement = Statement('What is log ( 5 + 6 ) * sqrt ( 12 ) ?')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for including tests!

confidence, response = self.adapter.process(statement)
self.assertEqual(response.text, 'log ( ( 5 + ( 6 ) * sqrt ( ( 12 ) ) ) ) = 3.24977779033')