Repository: nltk/nltk

Issue:
Bug introduced in nltk 3.5 leads to nondeterministic behavior in nltk.sentiment.vader
Test script test.py
```python
#!/usr/bin/env python3

import json
from nltk.sentiment.vader import SentimentIntensityAnalyzer

line="BUT fuck but thats it"

si = SentimentIntensityAnalyzer()
print(json.dumps(si.polarity_scores(line), sort_keys=True))
```

Run it multiple times and compare outputs
```shell
$ for ((i=0;i<10;i++)); do ./test.py; done | sort | uniq -c
      4 {"compound": -0.3071, "neg": 0.36, "neu": 0.64, "pos": 0.0}
      6 {"compound": -0.6956, "neg": 0.543, "neu": 0.457, "pos": 0.0}
```

The problem is this method
https://github.com/nltk/nltk/blob/b0cd83ded0c3c2394f878d8577d71187fa3f9ae4/nltk/sentiment/vader.py#L451-L460

The core of the probem is relying on order in sets which is random:
```shell
$ for ((i=0;i<10;i++)); do python -c "print(set(['BUT', 'but']))"; done | sort | uniq -c
      7 {'but', 'BUT'}
      3 {'BUT', 'but'}
```

So in one case `_but_check` triggers one `BUT`, in another case it triggers another `but`. That's why test.py dumps different scores for the same string.

The original text to trigger the error was this reddit comment:
```
We've got some studs prospects, but thats all they are, prospects. BUT FUCK WE WON THE LOTTERY
```



Discussion:

Resolving patch:
diff --git a/nltk/sentiment/vader.py b/nltk/sentiment/vader.py
--- a/nltk/sentiment/vader.py
+++ b/nltk/sentiment/vader.py
@@ -449,7 +449,8 @@ def _least_check(self, valence, words_and_emoticons, i):
         return valence
 
     def _but_check(self, words_and_emoticons, sentiments):
-        but = {"but", "BUT"} & set(words_and_emoticons)
+        words_and_emoticons = [w_e.lower() for w_e in words_and_emoticons]
+        but = {"but"} & set(words_and_emoticons)
         if but:
             bi = words_and_emoticons.index(next(iter(but)))
             for sidx, sentiment in enumerate(sentiments):


Test patch:
diff --git a/nltk/test/sentiment.doctest b/nltk/test/sentiment.doctest
--- a/nltk/test/sentiment.doctest
+++ b/nltk/test/sentiment.doctest
@@ -105,6 +105,7 @@ Vader
     ...    "I won't say that the movie is astounding and I wouldn't claim that \
     ...    the movie is too banal either.",
     ...    "I like to hate Michael Bay films, but I couldn't fault this one",
+    ...    "I like to hate Michael Bay films, BUT I couldn't help but fault this one",
     ...    "It's one thing to watch an Uwe Boll film, but another thing entirely \
     ...    to pay for it",
     ...    "The movie was too good",
@@ -168,7 +169,7 @@ Vader
     Today SUX!
     compound: -0.5461, neg: 0.779, neu: 0.221, pos: 0.0,
     Today kinda sux! But I'll get by, lol
-    compound: 0.2228, neg: 0.195, neu: 0.531, pos: 0.274,
+    compound: 0.5249, neg: 0.138, neu: 0.517, pos: 0.344,
     It was one of the worst movies I've seen, despite good reviews.
     compound: -0.7584, neg: 0.394, neu: 0.606, pos: 0.0,
     Unbelievably bad acting!!
@@ -201,6 +202,8 @@ Vader
     compound: 0.4215, neg: 0.0, neu: 0.851, pos: 0.149,
     I like to hate Michael Bay films, but I couldn't fault this one
     compound: 0.3153, neg: 0.157, neu: 0.534, pos: 0.309,
+    I like to hate Michael Bay films, BUT I couldn't help but fault this one
+    compound: -0.1531, neg: 0.277, neu: 0.477, pos: 0.246,
     It's one thing to watch an Uwe Boll film, but another thing entirely to pay for it
     compound: -0.2541, neg: 0.112, neu: 0.888, pos: 0.0,
     The movie was too good