Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
api_key.rb
2 changes: 2 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--color
--format documentation
23 changes: 15 additions & 8 deletions lib/api.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
require "open-uri"
require "json"
require "ostruct"
require "naught"
require_relative "./movie"
class Api
require_relative "./api_key"

NullObject = Naught.build do |config|
config.define_explicit_conversions
end

APIKEY="4t6456xa33z8qhcqyuqgnkjh"
class Api

def self.search_by_title(title)
url = "http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=#{APIKEY}&q=#{URI.encode(title)}&page_limit=1"
struct = OpenStruct.new(get_url_as_json(url).fetch("movies").first)
Movie.new(id: struct.id.to_i,
title: struct.title,
year: struct.year,
score: struct.ratings["critics_score"]
)
struct.id.nil? ? NullObject.new : store_movie(struct)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!!

Only comment: rather than "store_movie", recommend "build_movie". Store tends to imply persistence.

end


def self.get_url_as_json(url)
JSON.parse(open(url).read)
end

def self.store_movie(movie_struct)
Movie.new(id: movie_struct.id.to_i,
title: movie_struct.title,
year: movie_struct.year,
score: movie_struct.ratings["critics_score"]
)
end
end
112 changes: 98 additions & 14 deletions movie_json.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,105 @@
require_relative "lib/movie"
require_relative "lib/api"

def find_movie
puts "OH HAI. Search?"
movie_title = gets
movie = Api.search_by_title(movie_title)
puts "Found: #{movie.title}. Score: #{movie.score}"
end
class MovieJson

attr_reader :movies
def initialize
@movies = []
end

find_movie
def run
search
end

while true do
puts "Search Again (Y/N)"
answer = gets.upcase[0]
if answer == "Y"
find_movie
else
break
def movie_search_prompt
puts "OH HAI. Please add a movie you like"
print ">>"
movie_title = gets.downcase.chomp
return "Sorry, but you have to actually enter something to search" if movie_title.empty?
puts "Cool, searching for #{movie_title}"
search = movie_search_by_title(movie_title)
return "Sorry we cannot find that movie" if search.title.nil?
add_to_movie_list(search)
puts movie_title != search.title ? "This is the closest we could find: #{search.title} was released in #{search.year}. It recieved a critics score of #{search.score}" : "#{search.title} was released in #{search.year}. It recieved a critics score of #{search.score}"
end

def movie_search_by_title(movie_title)
Api.search_by_title(movie_title)
end

def add_to_movie_list(movie)
@movies << movie
end

def search_again(response)
if response == "yes"
puts movie_search_prompt
elsif response == "no"
false
else
puts "I don't understand that"
end
end

def search
puts "Would you like to: \n1) Search\n2) Average rating?\n3) Average year?\n4) Calculate movie happiness?\n5) Exit?"
print ">>"
u_start = gets.chomp
if u_start == "1"
puts movie_search_prompt
while true
puts "Search Again? Yes or No"
re_search = gets.downcase.chomp
break if search_again(re_search) == false
end
search
elsif u_start == "2"
puts average_raiting
search
elsif u_start == "3"
puts average_year
search
elsif u_start == "4"
puts calculate_happiness
search
else
puts "Exiting..."
end
end

def average_raiting
@movies.map {|movie| movie.score}.reduce(:+).to_f / @movies.size
end

def average_year
avg_year = @movies.map { |movie| movie.year}.reduce(:+).to_f / @movies.size
avg_year.to_i
end

def sort_years(movies)
movies.map{ |movie| movie.year }.sort
end

def average_rating_by_year(movie_hash_by_year,year)
movies = movie_hash_by_year[year]
movies.map { |movie| movie.score }.reduce(:+) / movies.length
end

def movie_rating_slope(years,movie_hash_by_year)
years[0] - years[-1] != 0 ? (average_rating_by_year(movie_hash_by_year,years[-1]) - average_rating_by_year(movie_hash_by_year,years[0])).to_f / (years[-1] - years[0]).to_f : 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one method stands out as hard to read. This one is probably best to extract out for readability.

def movie_rating_slope(years,movie_hash_by_year)
  return 0 if years[0] - years[-1] == 0
  last_year_avg = average_rating_by_year(movie_hash_by_year, years.last)
  first_year_avg = average_rating_by_year(movie_hash_by_year, years.first)
  (last_year_avg - first_year_avg).to_f / (years.last - years.first)
end

end

def calculate_happiness
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method definitely works; it's hard to read though.

Could you rewrite it using the constraint that a method should be no more than 3 lines long?

slope = movie_rating_slope(sort_years(@movies),@movies.group_by {|movie| movie.year})
if slope == 0
return "You're neutral"
elsif slope > 0
return "You're getting happier!"
else
return "You're getting sadder"
end
end

end
MovieJson.new.run if __FILE__ == $PROGRAM_NAME
9 changes: 8 additions & 1 deletion spec/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

describe Api do

let(:movie) { Api.search_by_title("Forrest Gump") }
let(:movie) { Api.search_by_title("Forrest Gump") }

before do
Api.stub(:get_url_as_json) { JSON.parse(File.read("spec/fixtures/forrest.json")) }
Expand All @@ -24,4 +24,11 @@
it "should return the year" do
movie.year.should eq(1994)
end

it "should return a warning statement if movie was not found" do
Api.stub(:get_url_as_json) { JSON.parse(File.read("spec/fixtures/no_movie.json")) }
no_movie = Api.search_by_title("dfsfsfdf")
expect(no_movie.title).to be_nil
end

end
1 change: 1 addition & 0 deletions spec/fixtures/no_movie.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"total":0,"movies":[],"links":{"self":"http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=Forrest+Gump&page_limit=1&page=1","next":"http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=Forrest+Gump&page_limit=1&page=2"},"link_template":"http://api.rottentomatoes.com/api/public/v1.0/movies.json?q={search-term}&page_limit={results-per-page}&page={page-number}"}
97 changes: 97 additions & 0 deletions spec/movie_json_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
require_relative "../movie_json"
require_relative "../lib/api"
require_relative "../lib/movie"

describe MovieJson do

let(:movie) { Movie.new(id: "111",
title: "Forrest Gump",
year: 1994,
score: 71)
}
let(:happy_movie) { Movie.new(id: "112",
title: "Happy movie",
year: 1995,
score: 99)
}
let(:sad_movie) { Movie.new(id: "113",
title: "Sad movie",
year: 1995,
score: 1)
}
let(:movie_search) { MovieJson.new }

before do
# Api.stub(:get_url_as_json) { JSON.parse(File.read("spec/fixtures/forrest.json")) }
Api.stub(:search_by_title) {movie}
# MovieJson.stub(:gets).and_return("")
end

describe "#movie_search_by_title" do
it "should return a warning when no movie is entered into the search" do
# movie_search1 = MovieJson.new
movie_search.stub(:gets).and_return("")
movie_search.movie_search_prompt.should == "Sorry, but you have to actually enter something to search"
end
end

it "should allow the user to add two movies they like" do
# movie_search2 = MovieJson.new
movie_search.add_to_movie_list(movie)
movie_search.add_to_movie_list(movie)
expect(movie_search.movies.length).to eq(2)
end

describe "#average_raiting" do
it "should give average rating of the movies in your list" do
# movie_search3 = MovieJson.new
movie_search.add_to_movie_list(movie)
movie_search.add_to_movie_list(movie)
expect(movie_search.average_raiting).to eq(71)
end
end

describe "#average_year" do
it "should give the average year of the movies in your list" do
# movie_search4 = MovieJson.new
movie_search.add_to_movie_list(movie)
movie_search.add_to_movie_list(movie)
expect(movie_search.average_year).to eq(1994)
end
end

describe "#calculate_happiness" do
it "should say your neutral at neutral slope" do
# movie_search5 = MovieJson.new
movie_search.add_to_movie_list(movie)
movie_search.add_to_movie_list(movie)
movie_search.calculate_happiness.should == "You're neutral"
end

it "should say your happier at postive slope" do
# movie_search6 = MovieJson.new
movie_search.add_to_movie_list(movie)
Api.stub(:search_by_title) {happy_movie}
movie_search.add_to_movie_list(happy_movie)
movie_search.calculate_happiness.should == "You're getting happier!"
end

it "should say your sadder at negative slope" do
# movie_search7 = MovieJson.new
movie_search.add_to_movie_list(movie)
Api.stub(:search_by_title) {sad_movie}
movie_search.add_to_movie_list(sad_movie)
movie_search.calculate_happiness.should == "You're getting sadder"
end

it "should take the average of years that are the same and determine slope" do
# movie_search7 = MovieJson.new
movie_search.add_to_movie_list(movie)
Api.stub(:search_by_title) {sad_movie}
movie_search.add_to_movie_list(sad_movie)
Api.stub(:search_by_title) {happy_movie}
movie_search.add_to_movie_list(happy_movie)
movie_search.calculate_happiness.should == "You're getting sadder"
end
end
end
4 changes: 4 additions & 0 deletions spec/movie_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
require_relative "../lib/movie"




describe Movie do

it "should store the title, year, and score" do
Expand Down