diff --git a/pom.xml b/pom.xml index 111501f..7d4dbb2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.to - HW03 + HW 1.0-SNAPSHOT @@ -14,18 +14,10 @@ UTF-8 - com.google.code.gson gson - 2.11.0 - - - - - com.fasterxml.jackson.core - jackson-databind - 2.17.2 + 2.10.1 diff --git a/src/main/java/Rational/Rational.java b/src/main/java/Rational/Rational.java index 7bd840e..90ce780 100644 --- a/src/main/java/Rational/Rational.java +++ b/src/main/java/Rational/Rational.java @@ -4,7 +4,6 @@ public class Rational { private int numerator; private int denominator; - // Constructor public Rational(int numerator, int denominator) { if (denominator == 0) { throw new IllegalArgumentException("Denominator cannot be zero"); @@ -14,7 +13,6 @@ public class Rational { simplify(); } - // GCD helper for simplification private int gcd(int a, int b) { a = Math.abs(a); b = Math.abs(b); @@ -26,73 +24,62 @@ public class Rational { return a; } - // Simplify the fraction private void simplify() { int gcd = gcd(numerator, denominator); numerator /= gcd; denominator /= gcd; - - // Keep denominator positive if (denominator < 0) { numerator = -numerator; denominator = -denominator; } } - // COMPLETED - Instance method: this + other public Rational add(Rational other) { int newNumerator = this.numerator * other.denominator + other.numerator * this.denominator; int newDenominator = this.denominator * other.denominator; return new Rational(newNumerator, newDenominator); } - // COMPLETED - Static method: r1 + r2 public static Rational add(Rational r1, Rational r2) { return r1.add(r2); } - // TODO: Instance method - this - other - // Formula: a/b - c/d = (a*d - c*b) / (b*d) + // 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 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) + // (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 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) + // (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 + if (other.numerator == 0) { + throw new IllegalArgumentException("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 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 @Override public String toString() { if (denominator == 1) { @@ -101,7 +88,6 @@ public class Rational { return numerator + "/" + denominator; } - // PROVIDED - Decimal value public double toDouble() { return (double) numerator / denominator; } diff --git a/src/main/java/movie/apis/Main.java b/src/main/java/movie/apis/Main.java index f0e713d..3d0bfa2 100644 --- a/src/main/java/movie/apis/Main.java +++ b/src/main/java/movie/apis/Main.java @@ -21,15 +21,16 @@ public class Main { break; case 2: - // TODO: Get genre ID and page from user, then call movieService.displayMoviesByGenre() + Long genreId = getLongInput("Enter Genre ID: "); + Long page = getLongInput("Enter Page number: "); + movieService.displayMoviesByGenre(genreId, page); break; - case 3: - // TODO (BONUS): Get movie ID from user, then call movieService.displayMovieDetails() - + Long movieId = getLongInput("Enter Movie ID: "); + movieService.displayMovieDetails(movieId); break; case 0: diff --git a/src/main/java/movie/apis/Movie.java b/src/main/java/movie/apis/Movie.java index 969774a..6b5b94f 100644 --- a/src/main/java/movie/apis/Movie.java +++ b/src/main/java/movie/apis/Movie.java @@ -1,24 +1,71 @@ package movie.apis; +import com.google.gson.annotations.SerializedName; 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; - private List images; private String year; - private String imdb_rating; private String country; - // TODO: Create a constructor with all fields + // استفاده از SerializedName برای تطبیق دقیق با کلیدهای JSON + @SerializedName("imdb_rating") + private String imdbRating; - // TODO: Create a simple constructor with id and title only + @SerializedName("imdb_votes") + private String imdbVotes; - // TODO: Create getters and setters for all fields + private String director; + private String actors; + private String plot; + private String awards; + private String rated; + private String runtime; + + private List genres; + private List images; + + // Constructor کامل + public Movie(Long id, String title, String year, String country, String imdbRating, String imdbVotes, + String director, String actors, String plot, String awards, String rated, String runtime, + List genres, List images) { + this.id = id; + this.title = title; + this.year = year; + this.country = country; + this.imdbRating = imdbRating; + this.imdbVotes = imdbVotes; + this.director = director; + this.actors = actors; + this.plot = plot; + this.awards = awards; + this.rated = rated; + this.runtime = runtime; + this.genres = genres; + this.images = images; + } + + // Constructor ساده + public Movie(Long id, String title) { + this.id = id; + this.title = title; + } + + // Getters and Setters + public Long getId() { return id; } + public void setId(Long id) { this.id = id; } + public String getTitle() { return title; } + public void setTitle(String title) { this.title = title; } + public String getYear() { return year; } + public void setYear(String year) { this.year = year; } + public String getImdbRating() { return imdbRating; } + public String getImdbVotes() { return imdbVotes; } + public String getDirector() { return director; } + public String getActors() { return actors; } + public String getPlot() { return plot; } + public String getAwards() { return awards; } + public String getRated() { return rated; } + public String getRuntime() { return runtime; } + public String getGenre() { return genres != null ? String.join(", ", genres) : "N/A"; } } \ 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..037b7e8 100644 --- a/src/main/java/movie/apis/MovieService.java +++ b/src/main/java/movie/apis/MovieService.java @@ -87,106 +87,77 @@ 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 try { - // Your code here + // ۱. گرفتن داده از API + String jsonResponse = getMoviesByGenreList(genreId, page); + if (jsonResponse == null) return; + + // ۲. تبدیل به شیء JSON + JsonObject root = JsonParser.parseString(jsonResponse).getAsJsonObject(); + JsonArray moviesArray = root.getAsJsonArray("movies"); + + // ۳. تبدیل JSON به لیست اشیاء Movie + Gson gson = new Gson(); + Type listType = new TypeToken>(){}.getType(); + List movies = gson.fromJson(moviesArray, listType); + + // ۴. چاپ لیست + for (Movie m : movies) { + System.out.println("ID: " + m.getId() + " | " + m.getTitle() + " (" + m.getYear() + ")"); + } + + // ۵. چاپ متادیتا + System.out.println("Total: " + root.get("total").getAsInt() + + " | Total Pages: " + root.get("total_pages").getAsInt()); } catch (Exception e) { System.err.println("ERROR: " + e.getMessage()); } } - /** * BONUS: Fetch movie details from API using movie ID * URL format: https://api.meshcomp.ir/api/v1/movies/{movieId} */ private String getMovieById(Long movieId) { try { - // TODO: Complete this method - // String url = MOVIE_BY_ID_URL + movieId; - // HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).build(); - // HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - // if (response.statusCode() == 200) return response.body(); + String url = MOVIE_BY_ID_URL + movieId; + HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - return null; + if (response.statusCode() == 200) return response.body(); } catch (Exception e) { System.out.println("!!Exception : " + e.getMessage()); } return null; } - /* - BONUS TODO: Display complete movie details for a given movie ID - - Open this link in your browser (and check Pretty-print checkbox) to view json format: - https://api.meshcomp.ir/api/v1/movies/1 - - INSTRUCTIONS: - 1. Call getMovieById(movieId) to get the JSON response string - 2. Check if response is null (if yes, print error and return) - 3. Parse the JSON string to JsonObject (inside try-catch) - 4. Use Gson to extract all fields from the JSON and map them to your Movie class: - - Add missing JSON fields to your Movie class first (actors, awards, director, - imdb_id, imdb_votes, metascore, plot, rated, released, runtime, type, writer) - - Then use Gson to parse your json string - 5. Print all movie details in a readable format - - (PUT ALL PARSING CODE INSIDE THE EXISTING try-catch) - */ - - /* EXAMPLE OUTPUT: - - ======================================================================= - THE SHAWSHANK REDEMPTION (1994) - ======================================================================= - Rating: 9.3/10 | Votes: 1,738,596 - Director: Frank Darabont - Cast: Tim Robbins, Morgan Freeman, Bob Gunton, William Sadler - Genre: Crime, Drama - Runtime: 142 min | Rated: R - Country: USA | Released: 14 Oct 1994 - Plot: Two imprisoned men bond over a number of years, finding - solace and eventual redemption through acts of common decency. - Awards: Nominated for 7 Oscars. Another 19 wins & 30 nominations. - ======================================================================= - - */ - public void displayMovieDetails(Long movieId) { - // Step 1: Get JSON response from API String jsonResponse = getMovieById(movieId); - - // Step 2: Check if we got valid data - // Step 3-5: Parse JSON and display details (PUT YOUR CODE INSIDE try-catch) if (jsonResponse == null) { System.out.println("Failed to get movie details for ID: " + movieId); return; } try { - // TODO: Parse jsonResponse to JsonObject - // HINT: Use JsonParser.parseString(jsonResponse).getAsJsonObject() - // TODO: use Gson to parse the json - // Your code here: + Gson gson = new Gson(); + // تبدیل JSON به آبجکت Movie + Movie m = gson.fromJson(jsonResponse, Movie.class); + + // چاپ با فرمت خواسته شده + System.out.println("======================================================================="); + System.out.println(" " + m.getTitle().toUpperCase() + " (" + m.getYear() + ")"); + System.out.println("======================================================================="); + System.out.println("Rating: " + m.getImdbRating() + "/10 | Votes: " + m.getImdbVotes()); + System.out.println("Director: " + m.getDirector()); + System.out.println("Cast: " + m.getActors()); + System.out.println("Genre: " + m.getGenre()); + System.out.println("Runtime: " + m.getRuntime() + " | Rated: " + m.getRated()); + System.out.println("Plot: " + m.getPlot()); + System.out.println("Awards: " + m.getAwards()); + System.out.println("======================================================================="); } catch (Exception e) { System.err.println("ERROR parsing movie details: " + e.getMessage()); } - } + } } \ No newline at end of file