Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.
Closed
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
35 changes: 35 additions & 0 deletions codecov/sentiment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from textblob import TextBlob


class SentimentAnalyzer:
def __init__(self):
pass

def get_sentiment(self, sentence: str) -> str:
polarity = self._get_polarity(sentence)
if polarity > 0:
return "positive"
elif polarity < 0:
return "negative"
else:
return "neutral"

def get_polarity_score(self, sentence: str) -> float:
return self._get_polarity(sentence)

def get_subjectivity_score(self, sentence: str) -> float:
return self._get_subjectivity(sentence)

def is_neutral(self, sentence: str) -> bool:
return self.get_sentiment(sentence) == "neutral"

def is_positive(self, sentence: str) -> bool:
return self.get_sentiment(sentence) == "positive"

def _get_polarity(self, sentence: str) -> float:
analysis = TextBlob(sentence)
return analysis.sentiment.polarity

def _get_subjectivity(self, sentence: str) -> float:
analysis = TextBlob(sentence)
return analysis.sentiment.subjectivity
76 changes: 76 additions & 0 deletions codecov/tests/test_sentiment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from unittest.mock import patch

import pytest

from codecov.sentiment import SentimentAnalyzer


@pytest.fixture
def sentiment_analyzer():
return SentimentAnalyzer()


@patch("codecov.sentiment.TextBlob")
def test_get_sentiment_positive(mock_textblob, sentiment_analyzer):
mock_textblob.return_value.sentiment.polarity = 0.5
assert sentiment_analyzer.get_sentiment("Great job!") == "positive"


@patch("codecov.sentiment.TextBlob")
def test_get_sentiment_negative(mock_textblob, sentiment_analyzer):
mock_textblob.return_value.sentiment.polarity = -0.5
assert sentiment_analyzer.get_sentiment("Terrible experience.") == "negative"


@patch("codecov.sentiment.TextBlob")
def test_get_sentiment_neutral(mock_textblob, sentiment_analyzer):
mock_textblob.return_value.sentiment.polarity = 0.0
assert sentiment_analyzer.get_sentiment("This is a neutral statement.") == "neutral"


@patch("codecov.sentiment.TextBlob")
def test_get_polarity_score(mock_textblob, sentiment_analyzer):
mock_textblob.return_value.sentiment.polarity = 0.75
assert sentiment_analyzer.get_polarity_score("Excellent work!") == 0.75


@patch("codecov.sentiment.TextBlob")
def test_get_subjectivity_score(mock_textblob, sentiment_analyzer):
mock_textblob.return_value.sentiment.subjectivity = 0.6
assert sentiment_analyzer.get_subjectivity_score("I think this is amazing!") == 0.6


@patch("codecov.sentiment.TextBlob")
def test_is_neutral_true(mock_textblob, sentiment_analyzer):
mock_textblob.return_value.sentiment.polarity = 0.0
assert sentiment_analyzer.is_neutral("This is a fact.") == True


@patch("codecov.sentiment.TextBlob")
def test_is_neutral_false(mock_textblob, sentiment_analyzer):
mock_textblob.return_value.sentiment.polarity = 0.5
assert sentiment_analyzer.is_neutral("This is great!") == False


@patch("codecov.sentiment.TextBlob")
def test_is_positive_true(mock_textblob, sentiment_analyzer):
mock_textblob.return_value.sentiment.polarity = 0.5
assert sentiment_analyzer.is_positive("This is wonderful!") == True


@patch("codecov.sentiment.TextBlob")
def test_is_positive_false(mock_textblob, sentiment_analyzer):
mock_textblob.return_value.sentiment.polarity = -0.5
assert sentiment_analyzer.is_positive("This is awful.") == False


@patch("codecov.sentiment.TextBlob")
def test_private_get_polarity(mock_textblob, sentiment_analyzer):
mock_textblob.return_value.sentiment.polarity = 0.8
assert sentiment_analyzer._get_polarity("Amazing!") == 0.8


@patch("codecov.sentiment.TextBlob")
def test_private_get_subjectivity(mock_textblob, sentiment_analyzer):
mock_textblob.return_value.sentiment.subjectivity = 0.9
assert sentiment_analyzer._get_subjectivity("I absolutely love this!") == 0.9
2 changes: 2 additions & 0 deletions requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pre-commit
psycopg2
PyJWT
pydantic
nltk==3.8.1
textblob==0.17.1
pytest>=7.2.0
pytest-cov
pytest-django
Expand Down
20 changes: 18 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ click==8.1.7
# click-didyoumean
# click-plugins
# click-repl
# nltk
click-didyoumean==0.3.0
# via celery
click-plugins==1.1.1
Expand Down Expand Up @@ -177,6 +178,7 @@ freezegun==1.1.0
# via -r requirements.in
google-api-core[grpc]==2.11.1
# via
# google-api-core
# google-cloud-core
# google-cloud-pubsub
# google-cloud-storage
Expand Down Expand Up @@ -249,6 +251,8 @@ jmespath==0.10.0
# via
# boto3
# botocore
joblib==1.4.2
# via nltk
jsonschema==4.14.0
# via drf-spectacular
kombu==5.3.6
Expand All @@ -263,6 +267,10 @@ monotonic==1.5
# via analytics-python
multidict==4.7.6
# via yarl
nltk==3.8.1
# via
# -r requirements.in
# textblob
nodeenv==1.5.0
# via pre-commit
oauth2==1.9.0.post1
Expand Down Expand Up @@ -397,7 +405,9 @@ redis==4.4.4
# python-redis-lock
# shared
regex==2023.12.25
# via -r requirements.in
# via
# -r requirements.in
# nltk
requests==2.32.3
# via
# -r requirements.in
Expand All @@ -408,7 +418,9 @@ requests==2.32.3
# shared
# stripe
rfc3986[idna2008]==1.4.0
# via httpx
# via
# httpx
# rfc3986
rsa==4.7.2
# via google-auth
s3transfer==0.5.0
Expand Down Expand Up @@ -455,10 +467,14 @@ stripe==9.6.0
# via -r requirements.in
text-unidecode==1.3
# via faker
textblob==0.17.1
# via -r requirements.in
tlslite-ng==0.8.0b1
# via shared
toml==0.10.2
# via pre-commit
tqdm==4.66.6
# via nltk
typing==3.7.4.3
# via shared
typing-extensions==4.6.2
Expand Down
Loading