3

I've been stuck here for a while, any help would be appreciated, thanks I'm getting this error on the console while trying to run ./tweets @cs50:

~/workspace/pset6/sentiments/ $ ./tweets @cs50 Traceback (most recent call last): File "./tweets", line 42, in main() File "./tweets", line 32, in main score = analyzer.analyze(tweets) File "/home/ubuntu/workspace/pset6/sentiments/analyzer.py", line 32, in analyze tokens = tokenizer.tokenize(text) File "/home/ubuntu/.local/lib/python3.4/site-packages/nltk/tokenize/casual.py", line 294, in tokenize text = _replace_html_entities(text) File "/home/ubuntu/.local/lib/python3.4/site-packages/nltk/tokenize/casual.py", line 258, in _replace_html_entities return ENT_RE.sub(_convert_entity, _str_to_unicode(text, encoding)) TypeError: expected string or buffer

here is my analyzer.py:

import nltk

class Analyzer():
"""Implements sentiment analysis."""

def __init__(self, positives, negatives):
    """Initialize Analyzer."""

    # TODO load positive and negative words
    self.positives = []
    with open("positive-words.txt", "r") as pwords:
        for line in pwords:
            if line.startswith(";") and line.startswith(" "):
                pass
            else:
                self.positives.extend(line.split())

    self.negatives = []
    with open("negative-words.txt", "r") as nwords:
        for line in nwords:
            if line.startswith(";") and line.startswith(" "):
                pass
            else:
                self.negatives.extend(line.split())


def analyze(self, text):
    """Analyze text for sentiment, returning its score."""

    # TODO assign each word in text a value -1, 0, 1, calculate texts total score
    tokenizer = nltk.tokenize.TweetTokenizer()
    tokens = tokenizer.tokenize(text)
    score = 0
    for token in tokens:
        token.lower()
        if token in self.positives:
            score += 1
        elif token in self.negatives:
            score -= 1
    return score

and my tweets:

#!/usr/bin/env python3

# TODO
import sys
import os
import helpers
from termcolor import colored
from analyzer import Analyzer

def main():
#ensure proper usage:
if len(sys.argv) != 2:
    sys.exit("Error, usage: ./tweets @user")
user = sys.argv[1].lstrip("@")

# absolute paths to lists
positives = os.path.join(sys.path[0], "positive-words.txt")
negatives = os.path.join(sys.path[0], "negative-words.txt")

#get tweets:
tweets = helpers.get_user_timeline(user, 50)

#check if successful
if tweets == None:
    sys.exit("Error, unable to access user's tweets")

#instantiate analyzer:
analyzer = Analyzer(positives, negatives)

#analyze tweets:
for tweet in tweets:
    score = analyzer.analyze(tweets)

    if score > 0:
        print(colored(":)", "green"))
    elif score < 0:
        print(colored(":(", "red"))
    else:
        print(colored(":|", "yellow"))

if __name__ == "__main__":
main()

and application.py:

from flask import Flask, redirect, render_template, request, url_for

import helpers
from analyzer import Analyzer

app = Flask(__name__)

@app.route("/")
def index():
return render_template("index.html")

@app.route("/search")
def search():

# validate screen_name
screen_name = request.args.get("screen_name", "").lstrip("@")
if not screen_name:
    return redirect(url_for("index"))

# get screen_name's tweets
tweets = helpers.get_user_timeline(screen_name)

# TODO redirect to index if none

if tweets == None:
    return redirect(url_for("index"))

positive, negative, neutral = 0.0, 0.0, 100.0

#initiate analyzer:
analyzer = Analyzer(positive, negative)

for tweet in tweets:
    score = analyzer.analyze(tweets)
    if score > 1:
        positive += 1
        neutral -= 1
    elif score < 1:
        negative += 1
        neutral -= 1


# generate chart
chart = helpers.chart(positive, negative, neutral)

# render results
return render_template("search.html", chart=chart,       screen_name=screen_name)

1 Answer 1

5

Maybe a simple typo in tweets here score = analyzer.analyze(tweets), since you want to send one tweet at a time.

Also, beware here: token.lower(). The lower method returns the string in lower case, it does not change the string to lower case. You might try ./smile LOVE or ./smile HATE to see what result you get.

2
  • yes! it was a typo in both tweets and application.py. Also I have fixed token.lower() with adding additional line of code and changing the loop. But I just realized that there is another issue when calling ./tweets @user: it seems that I hard coded the smiley faces in tweets.py instead of implementing text from actual tweet.
    – bobby_pin
    Commented Mar 20, 2017 at 18:33
  • and that was an easy fix, thank you for your help!
    – bobby_pin
    Commented Mar 20, 2017 at 18:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .