bunyaminergen's picture
Initial
1b97239
# Standard library imports
from typing import Annotated, Dict, Any, List
class Annotator:
"""
A class to annotate a structured sentiment model (SSM) with various
attributes such as sentiment, profanity, summary, conflict, and topic.
Parameters
----------
ssm : list of dict
A list of dictionaries representing the structured sentiment model.
Attributes
----------
ssm : list of dict
The structured sentiment model to be annotated.
global_summary : str
The global summary of the annotations.
global_conflict : bool
The global conflict status of the annotations.
global_topic : str
The global topic of the annotations.
"""
def __init__(self, ssm: Annotated[List[Dict[str, Any]], "Structured Sentiment Model"]):
"""
Initializes the Annotator class with the provided SSM.
Parameters
----------
ssm : list of dict
A list of dictionaries representing the structured sentiment model.
"""
self.ssm = ssm
self.global_summary = ""
self.global_conflict = False
self.global_topic = "Unknown"
def add_sentiment(
self,
sentiment_results: Annotated[Dict[str, Any], "Sentiment analysis results"]
):
"""
Adds sentiment data to the SSM.
Parameters
----------
sentiment_results : dict
A dictionary containing sentiment analysis results, including
a "sentiments" key with a list of sentiment dictionaries.
Examples
--------
>>> annotator = Annotator([{"text": "example"}])
>>> results = {"sentiments": [{"index": 0, "sentiment": "Positive"}]}
>>> annotator.add_sentiment(sentiment_results)
"""
if len(sentiment_results["sentiments"]) != len(self.ssm):
print(f"Mismatch: SSM Length = {len(self.ssm)}, "
f"Sentiments Length = {len(sentiment_results['sentiments'])}")
print("Adjusting to match lengths...")
if len(sentiment_results["sentiments"]) < len(self.ssm):
for idx in range(len(sentiment_results["sentiments"]), len(self.ssm)):
sentiment_results["sentiments"].append({"index": idx, "sentiment": "Neutral"})
elif len(sentiment_results["sentiments"]) > len(self.ssm):
sentiment_results["sentiments"] = sentiment_results["sentiments"][:len(self.ssm)]
for sentiment_data in sentiment_results["sentiments"]:
idx = sentiment_data["index"]
if idx < len(self.ssm):
self.ssm[idx]["sentiment"] = sentiment_data["sentiment"]
else:
print(f"Skipping sentiment data at index {idx}, out of range.")
def add_profanity(
self,
profane_results: Annotated[Dict[str, Any], "Profanity detection results"]
) -> List[Dict[str, Any]]:
"""
Adds profanity data to the SSM.
Parameters
----------
profane_results : dict
A dictionary containing profanity detection results, including
a "profanity" key with a list of profanity dictionaries.
Returns
-------
list of dict
The updated SSM with profanity annotations.
Examples
--------
>>> annotator = Annotator([{"text": "example"}])
>>> results = {"profanity": [{"index": 0, "profane": True}]}
>>> annotator.add_profanity(profane_results)
"""
if "profanity" not in profane_results:
print("Warning: 'profanity' key is missing in profane_results.")
return self.ssm
if len(profane_results["profanity"]) != len(self.ssm):
print(f"Mismatch: SSM Length = {len(self.ssm)}, "
f"Profanity Length = {len(profane_results['profanity'])}")
print("Adjusting to match lengths...")
if len(profane_results["profanity"]) < len(self.ssm):
for idx in range(len(profane_results["profanity"]), len(self.ssm)):
profane_results["profanity"].append({"index": idx, "profane": False})
elif len(profane_results["profanity"]) > len(self.ssm):
profane_results["profanity"] = profane_results["profanity"][:len(self.ssm)]
for profanity_data in profane_results["profanity"]:
idx = profanity_data["index"]
if idx < len(self.ssm):
self.ssm[idx]["profane"] = profanity_data["profane"]
else:
print(f"Skipping profanity data at index {idx}, out of range.")
return self.ssm
def add_summary(
self,
summary_result: Annotated[Dict[str, str], "Summary results"]
) -> Dict[str, Any]:
"""
Adds a global summary to the annotations.
Parameters
----------
summary_result : dict
A dictionary containing a "summary" key with the summary text.
Returns
-------
dict
The updated SSM and global summary.
Examples
--------
>>> annotator = Annotator([{"text": "example"}])
>>> result = {"summary": "This is a summary."}
>>> annotator.add_summary(summary_result)
"""
if not summary_result or "summary" not in summary_result:
print("Warning: 'summary' key is missing in summary_result.")
return {"ssm": self.ssm, "summary": self.global_summary}
self.global_summary = summary_result["summary"]
return {"ssm": self.ssm, "summary": self.global_summary}
def add_conflict(
self,
conflict_result: Annotated[Dict[str, bool], "Conflict detection results"]
) -> Dict[str, Any]:
"""
Adds a global conflict status to the annotations.
Parameters
----------
conflict_result : dict
A dictionary containing a "conflict" key with a boolean value.
Returns
-------
dict
The updated SSM and global conflict status.
Examples
--------
>>> annotator = Annotator([{"text": "example"}])
>>> result = {"conflict": True}
>>> annotator.add_conflict(conflict_result)
"""
if not conflict_result or "conflict" not in conflict_result:
print("Warning: 'conflict' key is missing in conflict_result.")
return {"ssm": self.ssm, "conflict": self.global_conflict}
self.global_conflict = conflict_result["conflict"]
return {"ssm": self.ssm, "conflict": self.global_conflict}
def add_topic(
self,
topic_result: Annotated[Dict[str, str], "Topic detection results"]
) -> Dict[str, Any]:
"""
Adds a global topic to the annotations.
Parameters
----------
topic_result : dict
A dictionary containing a "topic" key with the topic name.
Returns
-------
dict
The updated SSM and global topic.
Examples
--------
>>> annotator = Annotator([{"text": "example"}])
>>> result = {"topic": "Technology"}
>>> annotator.add_topic(topic_result)
"""
if not topic_result or "topic" not in topic_result:
print("Warning: 'topic' key is missing in topic_result.")
return {"ssm": self.ssm, "topic": self.global_topic}
self.global_topic = topic_result["topic"]
return {"ssm": self.ssm, "topic": self.global_topic}
def finalize(self) -> Dict[str, Any]:
"""
Finalizes the annotations by returning the updated SSM along with
global annotations for summary, conflict, and topic.
Returns
-------
dict
A dictionary containing the updated SSM and global annotations.
Examples
--------
>>> annotator = Annotator([{"text": "example"}])
>>> annotator.finalize()
{'ssm': [{'text': 'example'}], 'summary': '', 'conflict': False, 'topic': 'Unknown'}
"""
return {
"ssm": self.ssm,
"summary": self.global_summary,
"conflict": self.global_conflict,
"topic": self.global_topic
}