Skip to content

Instantly share code, notes, and snippets.

@amcooper
Last active August 2, 2017 00:59
Show Gist options
  • Save amcooper/91d781215878a0eeb4629af770fd61b0 to your computer and use it in GitHub Desktop.
Save amcooper/91d781215878a0eeb4629af770fd61b0 to your computer and use it in GitHub Desktop.
Vigilant snippet no. 1

Snippet no. 1: the Tweet Controller (Ruby)

Introduction

Lesser Evil (lesser-evil-cli) is a hosted Ruby gem for the command line which applies a third-party, open-source sentiment analysis tool to collect negative-affect tweets regarding the 2016 U.S. Presidential candidates. The user chooses the candidate ("Trump" or "Clinton") and the negativity threshold ("angry" or "very angry").

What does it do?

The fetch_tweets method in the Tweet Controller is the primary engine of the application. It performs the following tasks:

  • Retrieves a batch of tweets. It calls (line 29) the get_batch method which makes GET requests to the Twitter Search API. The request includes search terms, desired number of results, and the maximum ID (i.e., the most recent ID from which to start the search)
  • Filters them according to sentiment. The if statement of line 36 tests for sentiment negativity and user-specified intensity
  • Creates a TweetSlim object from each matched tweet (line 37)
  • Prints each TweetSlim object to the screen
  • Saves each TweetSlim object to an array
  • Repeats the above steps until the desired number of matched tweets is reached (while loop of line 28)
  • Returns the array (line 44)

Why did I write this?

fetch_tweets is, as mentioned, the primary engine of the application, the method that does most of the work. In its current incarnation, the gem is a command-line application. But with some adjustments it can do double-duty, functioning additionally as part of a full-stack application. The second snippet comprises a couple of React components that are the beginning of that app.

class LesserEvil::TweetController
attr_accessor :result, :candidate, :is_intense, :sentiment, :fast_print, :tweet_qty, :batch_qty
def initialize(options)
@result = []
@candidate = options[:candidate]
@is_intense = options[:is_intense]
@sentiment = options[:sentiment] || "Negative"
@fast_print = options[:fast_print] == nil ? true : options[:fast_print]
@tweet_qty = options[:tweet_qty] || LesserEvil::DEFAULT_TWEET_QTY
@batch_qty = options[:batch_qty] || LesserEvil::DEFAULT_BATCH_QTY
end
def get_batch(candidate,is_intense,max_id = nil)
response = HTTParty.get("#{LesserEvil::BASE_TWITTER_URL}?q=#{LesserEvil::SEARCH_TERMS[candidate.to_sym]}&count=#{@batch_qty}&max_id=#{max_id}", headers: {"Authorization" => LesserEvil::APP_AUTH})
response["statuses"]
end
def get_sentiment(text)
options = { body: { txt: text }}
response = HTTParty.post(LesserEvil::SENTIMENT_URL, options)
response["result"]
end
def fetch_tweets
max_id = nil
while @result.length < @tweet_qty
batch = get_batch(@candidate,@is_intense,max_id)
max_id = batch.last["id"] - 1
index = 0
while index < batch.length && @result.length < @tweet_qty
status = batch[index]
sentiment_analysis = get_sentiment(status["text"])
intensity = @is_intense ? 1 : 0
if sentiment_analysis["sentiment"] == @sentiment && sentiment_analysis["confidence"].to_f >= 75 * intensity && @result.length < @tweet_qty
tweet_slim = TweetSlim.new(@candidate,status)
tweet_slim.prettyprint if @fast_print
@result << tweet_slim
end
index += 1
end
end
@result
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment