Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panda & Tiger level complete #10

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
18 changes: 11 additions & 7 deletions lib/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@
require_relative "./movie"
class Api

APIKEY="4t6456xa33z8qhcqyuqgnkjh"
APIKEY="u2wh4hkgt7xkuqh6bhgm7f83"

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"]
)
if !struct.id.nil?
Movie.new(id: struct.id.to_i,
title: struct.title,
year: struct.year,
score: struct.ratings["critics_score"]
)
else
puts "No Movies returned"
end
end


def self.get_url_as_json(url)
JSON.parse(open(url).read)
JSON.parse(open(url, 'User-Agent' => 'Ruby').read)
end

end
3 changes: 3 additions & 0 deletions lib/movie.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
class Movie

attr_reader :id, :title, :year, :score
attr_accessor :liked_at

def initialize(hash={})
@id = hash.fetch(:id)
@title = hash.fetch(:title)
@year = hash.fetch(:year)
@score = hash.fetch(:score)
@liked_at = Time.now.year
end
end
67 changes: 67 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
class User
attr_reader :name, :searches

def initialize(name)
@name = name
@searches = []
end

def add_to_searches(movie)
@searches << movie
end

def rating
searches.delete_if { |m| m == nil } # since we are returning a string when no movie is found, I'm removing any nil values
movie_scores = searches.map { |movie| movie.score }
movie_scores.inject { |sum, el| sum + el } / searches.size
end

def average_year
searches.delete_if { |m| m == nil }
movie_years = searches.map { |movie| movie.year }
movie_years.inject { |sum, el| sum + el } / searches.size
end

def average_rating_per_year
years_and_scores = searches.map { |movie| { movie.liked_at.to_s => movie.score }}
merged = Hash.new(0)
years_and_scores.each do |h|
h.each do |y|
if merged[y[0]].is_a?(Array)
merged[y[0]] << y[1]
else
merged[y[0]] = [y[1]]
end
end
end

output = {}
# Compute the average
merged.each do |m|
output[m[0]] = m[1].inject { |sum, el| sum + el } / m[1].length
end
output
end

def calculate_slope
avg_ratings = average_rating_per_year
key_array = []
avg_ratings.each_key { |key| key_array << key.to_i }
if key_array.size > 1
first_year = key_array.min
last_year = key_array.max
(avg_ratings[last_year.to_s] - avg_ratings[first_year.to_s]) / (last_year - first_year)
else
"No slope"
end
end

def picking_ability
if calculate_slope == "No slope"
"not yet determined."
else
calculate_slope > 0 ? "getting better." : "getting worse."
end
end
end

27 changes: 25 additions & 2 deletions movie_json.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,35 @@
require_relative "lib/movie"
require_relative "lib/api"
require_relative "lib/user"

def start_movie_finder
puts "OH HAI. What's your name?"
@user = User.new(gets)
end

def find_movie
puts "OH HAI. Search?"
puts "Add a movie you really like, #{@user.name}"
movie_title = gets
movie = Api.search_by_title(movie_title)
puts "Found: #{movie.title}. Score: #{movie.score}"
@user.add_to_searches(movie)
if !movie.nil?
puts "Found: #{movie.title}. Score: #{movie.score}"
end
end

def show_movie_searches
puts "============================"
puts "Your overall average movie rating score is: #{@user.rating}"
puts "The average year for the movies you have liked is: #{@user.average_year}"
puts "============================"
@user.average_rating_per_year.each_pair { |k, v| puts "For #{k}, your average movie rating was #{v}!"}
puts "Your picking ability is #{@user.picking_ability}"
puts "============================"
puts "Your search history:"
@user.searches.each { |movie| puts movie.title }
end

start_movie_finder
find_movie

while true do
Expand All @@ -16,6 +38,7 @@ def find_movie
if answer == "Y"
find_movie
else
show_movie_searches
break
end
end
31 changes: 24 additions & 7 deletions spec/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,32 @@
movie.title.should eq("Forrest Gump")
end

it "should return the score" do
movie.score.should eq(71)
end
context "when movie is found" do

it "should return the score" do
movie.score.should eq(71)
end

it "should return the id" do
movie.id.should eq(10036)
end

it "should return the id" do
movie.id.should eq(10036)
it "should return the year" do
movie.year.should eq(1994)
end
end

it "should return the year" do
movie.year.should eq(1994)
context "when movie is not found" do

before do
Api.stub(:get_url_as_json) { JSON.parse(File.read("spec/fixtures/no_movie.json")) }
end

let(:no_movie_found) { Api.search_by_title("No movies exists") }

it "doesn't raise an error" do
expect{:no_movie_found}.to_not raise_error(NoMethodError)
end
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=top+tomatoes&page_limit=1&page=1"},"link_template":"http://api.rottentomatoes.com/api/public/v1.0/movies.json?q={search-term}&page_limit={results-per-page}&page={page-number}"}
2 changes: 2 additions & 0 deletions spec/movie_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@

it "should store the title, year, and score" do
movie = Movie.new(id: "the-id", title: "the-title", year: 1998, score: 50)
movie.liked_at = 2012
movie.id.should eq("the-id")
movie.title.should eq("the-title")
movie.year.should eq(1998)
movie.score.should eq(50)
movie.liked_at.should eq(2012)
end

end
67 changes: 67 additions & 0 deletions spec/user_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require_relative "../lib/user"
require_relative "../lib/movie"
describe User do

let(:user) { User.new("Ralph") }
let(:movie) { Movie.new(id: "1", title: "First movie", year: 1985, score: 80) }
let(:second_movie) { Movie.new(id: "2", title: "Second movie", year: 2000, score: 60) }
let(:third_movie) { Movie.new(id: "3", title: "Third movie", year: 2000, score: 90) }


context "when user is initialized" do

it "has a name" do
expect(user.name).to eq("Ralph")
end

it "has an empty list of movie searches" do
expect(user.searches).to eq([])
end

it "can calculate the average rating per year" do
add_movies_to_searches(user)
average_ratings = user.average_rating_per_year
expect(average_ratings).to eq({"2012" => 70, "2010" => 90})
end

it "can calculate a total average movie rating score" do
add_movies_to_searches(user)
expect(user.rating).to eq 76
end

it "can calculate the average year of movies liked" do
add_movies_to_searches(user)
expect(user.average_year).to eq 1995
end

it "can calculate the slope of yearly average ratings" do
add_movies_to_searches(user)
expect(user.calculate_slope).to eq -10
end

it "can tell if user is getting worse at picking movies" do
add_movies_to_searches(user)
expect(user.picking_ability).to eq("getting worse.")
end
end

context "when searching" do

it "records a user's search" do
add_movies_to_searches(user)
expect(user.searches.first).to eq(movie)
end

it "records multiple searches" do
add_movies_to_searches(user)
expect(user.searches).to eq([movie, second_movie, third_movie])
end
end

def add_movies_to_searches(user)
third_movie.liked_at = 2010
user.add_to_searches(movie)
user.add_to_searches(second_movie)
user.add_to_searches(third_movie)
end
end