diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..112a63b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +api_key.rb \ No newline at end of file diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..16f9cdb --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--format documentation diff --git a/lib/api.rb b/lib/api.rb index a8d499c..780f1e5 100644 --- a/lib/api.rb +++ b/lib/api.rb @@ -1,19 +1,19 @@ 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) end @@ -21,4 +21,11 @@ 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 diff --git a/movie_json.rb b/movie_json.rb index d8a91d7..2692db9 100644 --- a/movie_json.rb +++ b/movie_json.rb @@ -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 + end + + def calculate_happiness + 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 diff --git a/spec/api_spec.rb b/spec/api_spec.rb index 9014106..f1d4e0c 100644 --- a/spec/api_spec.rb +++ b/spec/api_spec.rb @@ -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")) } @@ -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 diff --git a/spec/fixtures/no_movie.json b/spec/fixtures/no_movie.json new file mode 100644 index 0000000..4d925e7 --- /dev/null +++ b/spec/fixtures/no_movie.json @@ -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}"} \ No newline at end of file diff --git a/spec/movie_json_spec.rb b/spec/movie_json_spec.rb new file mode 100644 index 0000000..8c83053 --- /dev/null +++ b/spec/movie_json_spec.rb @@ -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 diff --git a/spec/movie_spec.rb b/spec/movie_spec.rb index 088bd37..84a7bfd 100644 --- a/spec/movie_spec.rb +++ b/spec/movie_spec.rb @@ -1,4 +1,8 @@ require_relative "../lib/movie" + + + + describe Movie do it "should store the title, year, and score" do