From f21383383aed20276e793d52b988cc5f8b0bb03e Mon Sep 17 00:00:00 2001 From: Amir Ali Amiri Date: Sat, 13 Jun 2026 15:23:25 +0330 Subject: [PATCH] Complete mandatory parts for Rational and Movie Explorer --- .idea/misc.xml | 2 +- pom.xml | 16 ++++- src/main/java/Rational/Rational.java | 53 ++++++++------- src/main/java/movie/apis/Main.java | 7 +- src/main/java/movie/apis/Movie.java | 78 +++++++++++++++++++--- src/main/java/movie/apis/MovieService.java | 66 ++++++++++++------ 6 files changed, 157 insertions(+), 65 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 5274667..115fd38 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 111501f..a84ae55 100644 --- a/pom.xml +++ b/pom.xml @@ -13,15 +13,25 @@ 23 UTF-8 + + + + central + https://repo.maven.apache.org/maven2 + + + aliyun-maven + https://maven.aliyun.com/repository/public + + + - com.google.code.gson gson - 2.11.0 + 2.10.1 - com.fasterxml.jackson.core jackson-databind diff --git a/src/main/java/Rational/Rational.java b/src/main/java/Rational/Rational.java index 7bd840e..9f00f39 100644 --- a/src/main/java/Rational/Rational.java +++ b/src/main/java/Rational/Rational.java @@ -51,45 +51,44 @@ public class Rational { return r1.add(r2); } - // TODO: Instance method - this - other - // Formula: a/b - c/d = (a*d - c*b) / (b*d) + //* Calculates the difference between this rational number and another. + //* Formula: (a/b) - (c/d) = (a*d - c*b) / (b*d) public Rational subtract(Rational other) { - // YOUR CODE HERE - return null; // Remove this line when implemented + int newNumerator = this.numerator * other.denominator - other.numerator * this.denominator; + int newDenominator = this.denominator * other.denominator; + return new Rational(newNumerator, newDenominator); } - - // TODO: Static method - r1 - r2 + //* Static helper method to subtract two rational numbers. public static Rational subtract(Rational r1, Rational r2) { - // YOUR CODE HERE - return null; // Remove this line when implemented + return r1.subtract(r2); } - - // TODO: Instance method - this * other - // Formula: (a/b) * (c/d) = (a*c) / (b*d) + //* Multiplies this rational number by another. + //* Formula: (a/b) * (c/d) = (a*c) / (b*d) public Rational multiply(Rational other) { - // YOUR CODE HERE - return null; // Remove this line when implemented + int newNumerator = this.numerator * other.numerator; + int newDenominator = this.denominator * other.denominator; + return new Rational(newNumerator, newDenominator); } - - // TODO: Static method - r1 * r2 + //* Static helper method to multiply two rational numbers. public static Rational multiply(Rational r1, Rational r2) { - // YOUR CODE HERE - return null; // Remove this line when implemented + return r1.multiply(r2); } - - // TODO: Instance method - this / other - // Formula: (a/b) ÷ (c/d) = (a*d) / (b*c) + //* Divides this rational number by another. + //* Division is performed by multiplying with the reciprocal of the other fraction. + //* Formula: (a/b) ÷ (c/d) = (a*d) / (b*c) public Rational divide(Rational other) { - // YOUR CODE HERE - // HINT: Division is multiplication by reciprocal - // Don't forget to check if other.numerator is zero! - return null; // Remove this line when implemented + // Check for division by zero before performing the calculation + if (other.numerator == 0) { + throw new ArithmeticException("Cannot divide by zero"); + } + int newNumerator = this.numerator * other.denominator; + int newDenominator = this.denominator * other.numerator; + return new Rational(newNumerator, newDenominator); } - // TODO: Static method - r1 / r2 + //* Static helper method to divide two rational numbers. public static Rational divide(Rational r1, Rational r2) { - // YOUR CODE HERE - return null; // Remove this line when implemented + return r1.divide(r2); } // PROVIDED - String representation diff --git a/src/main/java/movie/apis/Main.java b/src/main/java/movie/apis/Main.java index f0e713d..90b5a3c 100644 --- a/src/main/java/movie/apis/Main.java +++ b/src/main/java/movie/apis/Main.java @@ -21,8 +21,11 @@ public class Main { break; case 2: - // TODO: Get genre ID and page from user, then call movieService.displayMoviesByGenre() - + // Get genre ID and page from user, then call movieService.displayMoviesByGenre() + Long genreId= getLongInput("Enter Genre ID:"); + Long page =getLongInput("Enter Page Number:"); + // delegate the business logic execution to MovieService + movieService.displayMoviesByGenre(genreId, page); break; diff --git a/src/main/java/movie/apis/Movie.java b/src/main/java/movie/apis/Movie.java index 969774a..c39fb89 100644 --- a/src/main/java/movie/apis/Movie.java +++ b/src/main/java/movie/apis/Movie.java @@ -1,13 +1,6 @@ package movie.apis; - import java.util.List; - -/** - * Model class representing a movie - * Fields: id, title, genres, images - */ public class Movie { - private Long id; private String title; private List genres; @@ -15,10 +8,75 @@ public class Movie { private String year; private String imdb_rating; private String country; + //* Comprehensive constructor to initialize all available fields of a movie. + public Movie(Long id, String title, List genres, List images, String year, String imdb_rating, String country) { + this.id = id; + this.title = title; + this.genres = genres; + this.images = images; + this.year = year; + this.imdb_rating = imdb_rating; + this.country = country; + } + //* Simplified constructor used when only the basic identification is needed. + public Movie(Long id, String title) { + this.id = id; + this.title = title; + } + //* Getter and setter + public Long getId() { + return id; + } - // TODO: Create a constructor with all fields + public void setId(Long id) { + this.id = id; + } - // TODO: Create a simple constructor with id and title only + public String getTitle() { + return title; + } - // TODO: Create getters and setters for all fields + public void setTitle(String title) { + this.title = title; + } + + public List getGenres() { + return genres; + } + + public void setGenres(List genres) { + this.genres = genres; + } + + public List getImages() { + return images; + } + + public void setImages(List images) { + this.images = images; + } + + public String getYear() { + return year; + } + + public void setYear(String year) { + this.year = year; + } + + public String getImdb_rating() { + return imdb_rating; + } + + public void setImdb_rating(String imdb_rating) { + this.imdb_rating = imdb_rating; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } } \ No newline at end of file diff --git a/src/main/java/movie/apis/MovieService.java b/src/main/java/movie/apis/MovieService.java index 3f053f5..f137c1d 100644 --- a/src/main/java/movie/apis/MovieService.java +++ b/src/main/java/movie/apis/MovieService.java @@ -87,33 +87,55 @@ public class MovieService { } } - /** - * TODO 1: Display movies for a specific genre and page - * - * Open this link in your browser (and check Pretty-print checkbox) to view json format: - * https://api.meshcomp.ir/api/v1/genres/1/movies - * - * Steps: - * - Call getMoviesByGenreList(genreId, page) to get JSON - * - Parse JSON to JsonObject - * - Get "movies" array (NOT "data") - * - Loop through array and print: "ID: {id} | {title} ({year})" - * - Also print total and total_pages - * - * PUT ALL PARSING CODE INSIDE try-catch - */ - public void displayMoviesByGenre(Long genreId, Long page) { - // TODO: Write your code here - // All parsing code must be inside try-catch + public void displayMoviesByGenre(Long genreId,Long page){ + // Fetch raw JSON string response from the network API + String jsonResponse = getMoviesByGenreList(genreId, page); + + if (jsonResponse== null) { + System.out.println("Failed to get movies for this genre."); + return; + + } + try { - // Your code here + + // Parse the raw string into a JsonObject + JsonObject rootObject =JsonParser.parseString(jsonResponse).getAsJsonObject(); + + // Extract the 'movies' JSON array from the root object + JsonArray moviesArray = rootObject.getAsJsonArray("movies"); + // Define the collection type to safely convert JsonArray into List + Type movieListType = new TypeToken>(){}.getType(); + Gson gson = new Gson(); + List movies = gson.fromJson(moviesArray, movieListType); + // Iterate through the parsed movies list and safely print core details + System.out.println("\nMOVIES IN GENRE (Page " + page + "):"); + for (Movie movie : movies) { + // Safeguard against missing 'year' fields in the dataset + String year = movie.getYear() != null ? movie.getYear() : "N/A"; + System.out.println("ID: " + movie.getId() + " | " + movie.getTitle() + " (" + year + ")"); + } + + + //Extract and safely print pagination metadata if available + if (rootObject.has("metadata") && !rootObject.get("metadata").isJsonNull()) { + JsonObject metadata = rootObject.getAsJsonObject("metadata"); + + + // read fields as String to fully avoid conversion exceptions (e.g. String vs Int) + String total = metadata.has("total_count") ? metadata.get("total_count").getAsString() : "Unknown"; + String totalPages = metadata.has("page_count") ? metadata.get("page_count").getAsString() : "Unknown"; + + System.out.println("\nTotal Movies: " + total + " | Total Pages: " + totalPages); + } + System.out.println(); + } catch (Exception e) { - System.err.println("ERROR: " + e.getMessage()); + // Log parsing or structural anomalies without crashing the whole application + System.err.println("ERROR parsing movies: " + e.getMessage()); } } - - /** * BONUS: Fetch movie details from API using movie ID * URL format: https://api.meshcomp.ir/api/v1/movies/{movieId}