From 81a1bf306f7b99f0f6d0f1e463c15f564505bf38 Mon Sep 17 00:00:00 2001 From: ardder Date: Wed, 3 Jul 2013 23:19:03 +0800 Subject: [PATCH 1/3] Panda level finished --- lib/api.rb | 6 ++++- movie_json.rb | 9 +++++-- spec/api_spec.rb | 47 +++++++++++++++++++++++++----------- spec/fixtures/no_result.json | 10 ++++++++ 4 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 spec/fixtures/no_result.json diff --git a/lib/api.rb b/lib/api.rb index a8d499c..fe9095e 100644 --- a/lib/api.rb +++ b/lib/api.rb @@ -8,7 +8,11 @@ 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_json = get_url_as_json(url).fetch("movies").first + + return nil unless movie_json + + struct = OpenStruct.new(movie_json) Movie.new(id: struct.id.to_i, title: struct.title, year: struct.year, diff --git a/movie_json.rb b/movie_json.rb index d8a91d7..a49c89d 100644 --- a/movie_json.rb +++ b/movie_json.rb @@ -3,9 +3,14 @@ def find_movie puts "OH HAI. Search?" - movie_title = gets + movie_title = gets.chomp movie = Api.search_by_title(movie_title) - puts "Found: #{movie.title}. Score: #{movie.score}" + + if movie + puts "Found: #{movie.title}. Score: #{movie.score}" + else + puts "Movie with title: \"#{movie_title}\" not found" + end end find_movie diff --git a/spec/api_spec.rb b/spec/api_spec.rb index 9014106..2298700 100644 --- a/spec/api_spec.rb +++ b/spec/api_spec.rb @@ -2,26 +2,45 @@ require "ostruct" describe Api do + context "Movie existed" 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")) } + end - before do - Api.stub(:get_url_as_json) { JSON.parse(File.read("spec/fixtures/forrest.json")) } - end + it "should search for movies" do + movie.title.should eq("Forrest Gump") + end - it "should search for movies" do - movie.title.should eq("Forrest Gump") - end + it "should return the score" do + movie.score.should eq(71) + end - 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 "Movie not existed" do + + before do + Api.stub(:get_url_as_json) { JSON.parse(File.read("spec/fixtures/no_result.json")) } + end + + it "should not raise exception" do + expect { + Api.search_by_title("NOTHINGFOUNDHERE") + }.to_not raise_error + end + + it "should return nil" do + movie = Api.search_by_title("NOTHINGFOUNDHERE") + movie.should be_nil + end end end diff --git a/spec/fixtures/no_result.json b/spec/fixtures/no_result.json new file mode 100644 index 0000000..9aaad2e --- /dev/null +++ b/spec/fixtures/no_result.json @@ -0,0 +1,10 @@ +{ + "total":0, + "movies":[ + + ], + "links":{ + "self":"http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=blahblah&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}" +} \ No newline at end of file From 90c54452f2413cc01c95f38724d2b6534278af31 Mon Sep 17 00:00:00 2001 From: ardder Date: Sat, 6 Jul 2013 13:15:26 +0800 Subject: [PATCH 2/3] Tiger level finished --- lib/movie.rb | 4 ++++ lib/movie_list.rb | 24 ++++++++++++++++++++++++ movie_json.rb | 26 ++++++++++++++++++-------- spec/movie_list_spec.rb | 33 +++++++++++++++++++++++++++++++++ spec/movie_spec.rb | 6 ++++++ 5 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 lib/movie_list.rb create mode 100644 spec/movie_list_spec.rb diff --git a/lib/movie.rb b/lib/movie.rb index 167a23e..0675f38 100644 --- a/lib/movie.rb +++ b/lib/movie.rb @@ -7,4 +7,8 @@ def initialize(hash={}) @year = hash.fetch(:year) @score = hash.fetch(:score) end + + def ==(movie) + return id == movie.id && title == movie.title && year == movie.year && score == movie.score + end end diff --git a/lib/movie_list.rb b/lib/movie_list.rb new file mode 100644 index 0000000..055ba64 --- /dev/null +++ b/lib/movie_list.rb @@ -0,0 +1,24 @@ +class MovieList + attr_reader :movies + + def initialize + @movies = [] + end + + def add(movie) + if @movies.include?(movie) + false + else + @movies << movie + true + end + end + + def average_score + @movies.inject(0.0) {|sum, movie| sum + movie.score} / @movies.count + end + + def titles + @movies.map(&:title).join(', ') + end +end \ No newline at end of file diff --git a/movie_json.rb b/movie_json.rb index a49c89d..a46572d 100644 --- a/movie_json.rb +++ b/movie_json.rb @@ -1,26 +1,36 @@ require_relative "lib/movie" +require_relative "lib/movie_list" require_relative "lib/api" def find_movie - puts "OH HAI. Search?" + puts "Add a movie you really like:" movie_title = gets.chomp movie = Api.search_by_title(movie_title) if movie puts "Found: #{movie.title}. Score: #{movie.score}" + movie else puts "Movie with title: \"#{movie_title}\" not found" + nil end end -find_movie +movie_list = MovieList.new while true do - puts "Search Again (Y/N)" - answer = gets.upcase[0] - if answer == "Y" - find_movie - else - break + movie = find_movie + + if movie + puts "[#{movie.title}] is already on your list!" unless movie_list.add(movie) + + puts "------------------------------------------" + puts "Your favorite movies: #{movie_list.titles}" + puts "Average score: #{movie_list.average_score}" + puts "------------------------------------------" end + + puts "Add more? (Y/N)" + answer = gets.upcase[0] + break if answer == "N" end diff --git a/spec/movie_list_spec.rb b/spec/movie_list_spec.rb new file mode 100644 index 0000000..9ba869f --- /dev/null +++ b/spec/movie_list_spec.rb @@ -0,0 +1,33 @@ +require_relative '../lib/movie' +require_relative '../lib/movie_list' + +describe MovieList do + + before(:each) do + @movie_list = MovieList.new + @movie_1 = Movie.new(id: '1', title: "movie-1", year: 2000, score: 50) + @movie_2 = Movie.new(id: '2', title: "movie-2", year: 2001, score: 60) + @movie_3 = Movie.new(id: '3', title: "movie-3", year: 2002, score: 85) + + @movie_list.add(@movie_1) + @movie_list.add(@movie_2) + @movie_list.add(@movie_3) + end + + it "should keep track of the movies we added" do + @movie_list.movies.should eq([@movie_1, @movie_2, @movie_3]) + end + + it "should calculate the average score" do + @movie_list.average_score.should eq((50+60+85).to_f/3) + end + + it "should display movie titles" do + @movie_list.titles.should eq("movie-1, movie-2, movie-3") + end + + it "should not add duplicated movie" do + @movie_list.add(@movie_1) + @movie_list.movies.count.should eq(3) + end +end \ No newline at end of file diff --git a/spec/movie_spec.rb b/spec/movie_spec.rb index 088bd37..3d5ab29 100644 --- a/spec/movie_spec.rb +++ b/spec/movie_spec.rb @@ -9,4 +9,10 @@ movie.score.should eq(50) end + it "should be equal to other movie with the same id, title, year, score" do + movie_1 = Movie.new(id: "1", title: "title1", year: 1998, score: 50) + movie_2 = Movie.new(id: "1", title: "title1", year: 1998, score: 50) + + (movie_1 == movie_2).should be_true + end end From 439e3bed0cc30f6c56cd9b59125bbc43a1554d02 Mon Sep 17 00:00:00 2001 From: ardder Date: Sat, 6 Jul 2013 14:52:41 +0800 Subject: [PATCH 3/3] Eagle level finished --- lib/movie_list.rb | 20 ++++++++++++++++++-- movie_json.rb | 16 +++++++++++++--- spec/movie_list_spec.rb | 29 +++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/lib/movie_list.rb b/lib/movie_list.rb index 055ba64..955f31a 100644 --- a/lib/movie_list.rb +++ b/lib/movie_list.rb @@ -1,8 +1,8 @@ class MovieList attr_reader :movies - def initialize - @movies = [] + def initialize(movies = []) + @movies = movies end def add(movie) @@ -18,6 +18,22 @@ def average_score @movies.inject(0.0) {|sum, movie| sum + movie.score} / @movies.count end + def average_year + @movies.inject(0.0) {|sum, movie| sum + movie.year} / @movies.count + end + + def slope + start_year = @movies.min_by {|movie| movie.year}.year + end_year = @movies.max_by {|movie| movie.year}.year + + return nil if start_year == end_year + + movies_in_start_year = @movies.select {|movie| movie.year == start_year} + movies_in_end_year = @movies.select {|movie| movie.year == end_year} + + (MovieList.new(movies_in_end_year).average_score - MovieList.new(movies_in_start_year).average_score) / (end_year - start_year).to_f + end + def titles @movies.map(&:title).join(', ') end diff --git a/movie_json.rb b/movie_json.rb index a46572d..ca0e5e5 100644 --- a/movie_json.rb +++ b/movie_json.rb @@ -24,10 +24,20 @@ def find_movie if movie puts "[#{movie.title}] is already on your list!" unless movie_list.add(movie) - puts "------------------------------------------" + slope = movie_list.slope + mood = if slope == nil || slope == 0 + "I can't determine your mood, maybe add more movie?" + elsif slope < 0 + "I think you are getting madder (index: #{slope.round(2).to_s})" + else + "I think you are getting happier (index: #{slope.round(2).to_s})" + end + + puts "-" * 80 puts "Your favorite movies: #{movie_list.titles}" - puts "Average score: #{movie_list.average_score}" - puts "------------------------------------------" + puts "Average score: #{movie_list.average_score.round(2)}" + puts mood + puts "-" * 80 end puts "Add more? (Y/N)" diff --git a/spec/movie_list_spec.rb b/spec/movie_list_spec.rb index 9ba869f..f9c94f6 100644 --- a/spec/movie_list_spec.rb +++ b/spec/movie_list_spec.rb @@ -22,6 +22,10 @@ @movie_list.average_score.should eq((50+60+85).to_f/3) end + it "should calculate the average year" do + @movie_list.average_year.should eq((2000+2001+2002).to_f/3) + end + it "should display movie titles" do @movie_list.titles.should eq("movie-1, movie-2, movie-3") end @@ -30,4 +34,29 @@ @movie_list.add(@movie_1) @movie_list.movies.count.should eq(3) end + + describe "#slope" do + it "should calculate the slope of rating correctly" do + @movie_4 = Movie.new(id: '4', title: 'movie-4', year: 2000, score: 60) + @movie_5 = Movie.new(id: '5', title: 'movie-5', year: 2010, score: 80) + @movie_6 = Movie.new(id: '6', title: 'movie-6', year: 2010, score: 90) + + @movie_list.add(@movie_4) + @movie_list.add(@movie_5) + @movie_list.add(@movie_6) + + score_of_2000 = (50+60).to_f / 2 + score_of_2010 = (80+90).to_f / 2 + + @movie_list.slope.should eq((score_of_2010 - score_of_2000) / (2010 - 2000).to_f) + end + + it "should return nil if all the movies are in the same year" do + movie_1 = Movie.new(id: '1', title: "movie-1", year: 2000, score: 50) + movie_2 = Movie.new(id: '2', title: "movie-2", year: 2000, score: 60) + movie_list = MovieList.new([movie_1, movie_2]) + + movie_list.slope.should be_nil + end + end end \ No newline at end of file