import logging
import spacy
from chatterbot.logic import LogicAdapter
from nltk.sentiment import SentimentIntensityAnalyzer
from sugaroid.brain.constants import GREET, BURN_IDK, I_AM
from sugaroid.brain.constants import WHAT_I_AM_GOING_TO_DO
from sugaroid.brain.ooo import Emotion
from sugaroid.brain.postprocessor import (
cosine_similarity,
random_response,
raw_in,
raw_lower_in,
)
from sugaroid.brain.whatamidoing import process_what_ami_doing
from sugaroid.core.statement import SugaroidStatement
[docs]class MeAdapter(LogicAdapter):
"""
Processes the statements showing possessive
"""
def __init__(self, chatbot, **kwargs):
super().__init__(chatbot, **kwargs)
self.normalized = None
self.tokenized = None
self.nlp = spacy.load("en_core_web_sm")
[docs] def can_process(self, statement):
# TODO Fix this
self.tokenized = self.nlp(str(statement))
for i in range(len(self.tokenized) - 1):
if self.tokenized[i].pos_ == "PRON" and str(
self.tokenized[i + 1].tag_
).startswith("VB"):
return True
else:
return False
[docs] def process(
self,
statement: SugaroidStatement,
additional_response_selection_parameters=None,
) -> SugaroidStatement:
response = "ok"
confidence = 0
emotion = Emotion.neutral
if raw_in("I", self.tokenized):
logging.info(
str(["{} {} {}".format(k, k.tag_, k.pos_) for k in self.tokenized])
)
# check if the pronoun has been reached yet, otherwise may detect some other nouns
start_scanning = False
for i in self.tokenized:
if i.pos_ == "PRON" and not i.tag_.startswith("W"):
start_scanning = True
if start_scanning:
pass
elif (
(i.pos_ != "PRON")
or (not start_scanning)
or (i.tag_.startswith("W"))
):
logging.info("MeAdapter: Skipping {} {}".format(i.lower_, i.tag_))
continue
logging.info("MeAdapter: Scanning :: {} : {}".format(i.text, i.pos_))
if (i.pos_ == "PROPN") or (i.tag_ == "NN"):
nn = i.text
if self.chatbot.globals["USERNAME"]:
response = (
"Are you sure you are {n}? I thought you were {u}".format(
n=nn, u=self.chatbot.globals["USERNAME"]
)
)
emotion = Emotion.wink
if i.pos_ == "PROPN":
confidence = 0.95
else:
confidence = 0.8
self.chatbot.globals["nn"] = nn
self.chatbot.globals["reversei"]["uid"] = 30000000001
self.chatbot.globals["reversei"]["type"] = bool
self.chatbot.globals["reversei"]["enabled"] = True
emotion = Emotion.non_expressive_left
break
else:
if not ("not" in str(statement)):
if i.lower_ == "sugaroid":
response = random_response(I_AM)
emotion = Emotion.lol
confidence = 0.95
else:
response = random_response(GREET).format(
str(nn).capitalize()
)
confidence = 0.9
self.chatbot.globals["USERNAME"] = nn
emotion = Emotion.positive
break
else:
response = "Ok!"
confidence = 0.5
emotion = Emotion.seriously
break
elif i.lower_ == "sugaroid":
response = random_response(I_AM)
emotion = Emotion.lol
confidence = 0.95
else:
sia = SentimentIntensityAnalyzer()
ps = sia.polarity_scores(str(i.sent))
confidence = 0.35
if ps["neu"] == 1:
response = "Ok! Thats great to hear from you"
emotion = Emotion.lol
elif ps["pos"] > ps["neg"]:
response = "Yay! I agree to you"
emotion = Emotion.positive
else:
confidence = 0.2
response = "Think again"
emotion = Emotion.non_expressive_left
elif raw_lower_in("you", self.tokenized):
logging.info(
str(["{} {} {}".format(k, k.tag_, k.pos_) for k in self.tokenized])
)
nn = ""
start_scanning = False
for i in self.tokenized:
if i.pos_ == "PRON" and not i.tag_.startswith("W"):
start_scanning = True
if start_scanning:
pass
elif (
(i.pos_ != "PRON")
or (not start_scanning)
or (i.tag_.startswith("W"))
):
logging.info(
"MeAdapter: Skipping {} {} ss={} {}".format(
i.lower_, i.tag_, not start_scanning, i.pos_
)
)
continue
logging.info("MeAdapter: Scanning :: {} : {}".format(i.text, i.pos_))
if i.pos_ == "ADJ":
try:
cos = cosine_similarity([str(i.lower_)], ["sugaroid"])
except ZeroDivisionError:
cos = 0.0
if i.lower_ == "sugaroid":
nn = i.text
response = "Yup, that's my name. I am sugaroid"
emotion = Emotion.lol
confidence = 0.9
break
elif cos > 0.9:
response = "Yes, you were close! My name is sugaroid"
emotion = Emotion.positive
confidence = 0.9
break
else:
if i.lower_ in ["human", "animal", "bird"]:
response = "No, I am not a {adj}. I am a robot".format(
adj=i.lower_
)
emotion = Emotion.angry_non_expressive
confidence = 0.9
else:
response = "seriously?"
emotion = Emotion.angry
confidence = 0.09
elif i.pos_ == "PROPN":
cos = cosine_similarity([str(i.lower_)], ["sugaroid"])
if i.lower_ == "sugaroid":
nn = i.text
response = "Yup, that's my name. I am sugaroid"
emotion = Emotion.lol
confidence = 0.9
break
elif cos > 0.9:
response = "Yes, you were close! My name is sugaroid"
emotion = Emotion.positive
confidence = 0.9
break
elif i.lower_ in WHAT_I_AM_GOING_TO_DO:
confidence = 0.4
response = "Perhaps, I will sit simply, and smile."
emotion = Emotion.lol
else:
nn = i.text
response = "Nope, I am not {n}, I am sugaroid".format(n=nn)
emotion = Emotion.angry
confidence = 0.9
elif i.tag_ == "NN":
if i.lower_ in ["bot", "robot", "computer", "silicon", "infant"]:
response = "You are right! I am a {}".format(i.lower_)
confidence = 0.9
emotion = Emotion.positive
elif i.lower_ in [
"human",
"bird",
"animal",
"tree",
"politician",
"player",
"liar",
"priest",
]:
response = "No way! I can't imagine myself to be a {}".format(
i.lower_
)
confidence = 0.9
emotion = Emotion.vomit
else:
logging.info(
"MeAdapter: Couldn't classify type of noun {}".format(
i.lower_
)
)
confidence = 0.9
sia = SentimentIntensityAnalyzer()
ps = sia.polarity_scores(str(i.sent))
if ps["neu"] == 1.0:
# try presence adapter pieces
presence_statement = process_what_ami_doing(statement)
if presence_statement.confidence == 0:
response = (
"I will need more time to learn if that actually makes sense with respect to "
"myself. "
)
emotion = Emotion.cry
else:
return presence_statement
elif ps["pos"] > ps["neg"]:
response = "I guess I am {}. Thanks!".format(i.text)
emotion = Emotion.wink
else:
response = "I am not {}! I am Sugaroid.".format(i.lower_)
emotion = Emotion.angry
elif i.tag_.startswith("VB"):
root_verb = i.lemma_
if root_verb in [
"say",
"tell",
"speak",
"murmur",
"blabber",
"flirt",
]:
response = random_response(BURN_IDK)
emotion = Emotion.lol
confidence = 0.8
else:
presence_statement = process_what_ami_doing(statement)
if presence_statement.confidence == 0:
# FIXME : Add more logic here
response = "Ok"
confidence = 0.05
emotion = Emotion.non_expressive_left
else:
return presence_statement
selected_statement = SugaroidStatement(response, chatbot=True)
selected_statement.confidence = confidence
selected_statement.emotion = emotion
return selected_statement