From d30d5659e4f23bedd29ff3d0705eb5d037a64a99 Mon Sep 17 00:00:00 2001 From: Gunther Cox Date: Fri, 1 Jan 2016 08:14:16 -0500 Subject: [PATCH] Added system adapter for case when database is empty. This is a new adapter that is now added by default when a new bot is created. The adapter is given the highest priority and will return a confidence value based on if there is data in the database. --- chatterbot/adapters/adaptation.py | 3 +++ chatterbot/adapters/logic/__init__.py | 1 + chatterbot/adapters/logic/base_match.py | 8 +++++++ chatterbot/adapters/logic/logic.py | 9 ++++++++ chatterbot/adapters/logic/multi_adapter.py | 9 ++++---- .../adapters/logic/no_knowledge_adapter.py | 23 +++++++++++++++++++ chatterbot/chatterbot.py | 8 ------- tests/test_adaptation.py | 4 +++- 8 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 chatterbot/adapters/logic/no_knowledge_adapter.py diff --git a/chatterbot/adapters/adaptation.py b/chatterbot/adapters/adaptation.py index 1e0d17a59..83cda258b 100644 --- a/chatterbot/adapters/adaptation.py +++ b/chatterbot/adapters/adaptation.py @@ -22,6 +22,9 @@ def __init__(self, **kwargs): self.logic = MultiLogicAdapter(**kwargs) self.logic.set_context(self) + # Add required system adapter + self.add_adapter("chatterbot.adapters.logic.NoKnowledgeAdapter") + def add_adapter(self, adapter, **kwargs): NewAdapter = import_module(adapter) diff --git a/chatterbot/adapters/logic/__init__.py b/chatterbot/adapters/logic/__init__.py index d522dffea..0ce5be6ba 100644 --- a/chatterbot/adapters/logic/__init__.py +++ b/chatterbot/adapters/logic/__init__.py @@ -2,3 +2,4 @@ from .closest_match import ClosestMatchAdapter from .closest_meaning import ClosestMeaningAdapter from .multi_adapter import MultiLogicAdapter +from .no_knowledge_adapter import NoKnowledgeAdapter diff --git a/chatterbot/adapters/logic/base_match.py b/chatterbot/adapters/logic/base_match.py index 1280a6728..0a8fb7493 100644 --- a/chatterbot/adapters/logic/base_match.py +++ b/chatterbot/adapters/logic/base_match.py @@ -44,6 +44,14 @@ def get(self, input_statement, statement_list=None): """ raise AdapterNotImplementedError() + def can_process(self, statement): + """ + Override the can_process method to check if the + storage context is available and there is at least + one statement in the database. + """ + return self.has_storage_context and self.context.storage.count() + def process(self, input_statement): # Select the closest match to the input statement diff --git a/chatterbot/adapters/logic/logic.py b/chatterbot/adapters/logic/logic.py index 8c214f968..a84b5421e 100644 --- a/chatterbot/adapters/logic/logic.py +++ b/chatterbot/adapters/logic/logic.py @@ -8,6 +8,15 @@ class LogicAdapter(Adapter): that all logic adapters should implement. """ + def can_process(self, statement): + """ + A preliminary check that is called to determine if a + logic adapter can process a given statement. By default, + this method returns true but it can be overridden in + child classes as needed. + """ + return True + def process(self, statement): """ Method that takes an input statement and returns diff --git a/chatterbot/adapters/logic/multi_adapter.py b/chatterbot/adapters/logic/multi_adapter.py index a51583c2e..95e6c329d 100644 --- a/chatterbot/adapters/logic/multi_adapter.py +++ b/chatterbot/adapters/logic/multi_adapter.py @@ -17,10 +17,11 @@ def process(self, statement): max_confidence = -1 for adapter in self.adapters: - confidence, output = adapter.process(statement) - if confidence > max_confidence: - result = output - max_confidence = confidence + if adapter.can_process(statement): + confidence, output = adapter.process(statement) + if confidence > max_confidence: + result = output + max_confidence = confidence return max_confidence, result diff --git a/chatterbot/adapters/logic/no_knowledge_adapter.py b/chatterbot/adapters/logic/no_knowledge_adapter.py new file mode 100644 index 000000000..b5da0928f --- /dev/null +++ b/chatterbot/adapters/logic/no_knowledge_adapter.py @@ -0,0 +1,23 @@ +from .logic import LogicAdapter + + +class NoKnowledgeAdapter(LogicAdapter): + """ + This is a system adapter that is automatically added + to the list of logic adapters durring initialization. + This adapter is placed at the beginning of the list + to be given the highest priority. + """ + + def process(self, statement): + """ + If there are no known responses in the database, + then a confidence of 1 should be returned with + the input statement. + Otherwise, a confidence of 0 should be returned. + """ + + if self.context.storage.count(): + return 0, statement + + return 1, statement diff --git a/chatterbot/chatterbot.py b/chatterbot/chatterbot.py index 1269c53a7..8c62cf916 100644 --- a/chatterbot/chatterbot.py +++ b/chatterbot/chatterbot.py @@ -71,14 +71,6 @@ def get_response(self, input_text): if not plugin_response is False: return self.io.process_response(Statement(plugin_response)) - # If no responses exist, return the input statement - if not self.storage.count(): - self.storage.update(input_statement) - self.recent_statements.append(input_statement) - - # Process the response output with the IO adapter - return self.io.process_response(input_statement) - # Select a response to the input statement confidence, response = self.logic.process(input_statement) diff --git a/tests/test_adaptation.py b/tests/test_adaptation.py index 7ef1ecf16..e0ea80fae 100644 --- a/tests/test_adaptation.py +++ b/tests/test_adaptation.py @@ -14,10 +14,12 @@ def test_add_storage_adapter(self): self.assertEqual(len(self.adaptation.storage_adapters), 1) def test_add_logic_adapter(self): + count_before = len(self.adaptation.logic.adapters) + self.adaptation.add_adapter( "chatterbot.adapters.logic.ClosestMatchAdapter" ) - self.assertEqual(len(self.adaptation.logic.adapters), 1) + self.assertEqual(len(self.adaptation.logic.adapters), count_before + 1) def test_add_io_adapter(self): self.adaptation.add_adapter(