From 406da4c211a589c7f4f83769045606784ce522cb Mon Sep 17 00:00:00 2001 From: DesertAndSand Date: Sat, 25 Apr 2026 12:31:58 +0330 Subject: [PATCH] fix: added implementations --- src/main/java/Rational/Rational.java | 99 ++++--- src/main/java/movie/apis/Genre.java | 24 +- src/main/java/movie/apis/Main.java | 43 ++- src/main/java/movie/apis/Movie.java | 289 ++++++++++++++++++++- src/main/java/movie/apis/MovieService.java | 151 ++++++----- 5 files changed, 477 insertions(+), 129 deletions(-) diff --git a/src/main/java/Rational/Rational.java b/src/main/java/Rational/Rational.java index 7bd840e..fbb98ba 100644 --- a/src/main/java/Rational/Rational.java +++ b/src/main/java/Rational/Rational.java @@ -1,108 +1,127 @@ package Rational; -public class Rational { +public class Rational +{ private int numerator; private int denominator; // Constructor - public Rational(int numerator, int denominator) { - if (denominator == 0) { + public Rational(int numerator, int denominator) + { + if (denominator == 0) throw new IllegalArgumentException("Denominator cannot be zero"); - } + this.numerator = numerator; this.denominator = denominator; simplify(); } // GCD helper for simplification - private int gcd(int a, int b) { + private int gcd(int a, int b) + { a = Math.abs(a); b = Math.abs(b); - while (b != 0) { + + while (b != 0) + { int temp = b; b = a % b; a = temp; } + return a; } // Simplify the fraction - private void simplify() { + private void simplify() + { int gcd = gcd(numerator, denominator); numerator /= gcd; denominator /= gcd; // Keep denominator positive - if (denominator < 0) { + if (denominator < 0) + { numerator = -numerator; denominator = -denominator; } } // COMPLETED - Instance method: this + other - public Rational add(Rational 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) { + public static Rational add(Rational r1, Rational r2) + { return r1.add(r2); } - // TODO: Instance method - this - other + // Instance method - this - other // 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 + public Rational subtract(Rational other) + { + 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 + // Static method - r1 - r2 + public static Rational subtract(Rational r1, Rational r2) + { + return r1.subtract(r2); } - // TODO: Instance method - this * other + // Instance method - this * other // Formula: (a/b) * (c/d) = (a*c) / (b*d) - public Rational multiply(Rational other) { - // YOUR CODE HERE - return null; // Remove this line when implemented + public Rational multiply(Rational other) + { + 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 + // Static method - r1 * r2 + public static Rational multiply(Rational r1, Rational r2) + { + return r1.multiply(r2); } - // TODO: Instance method - this / other + // Instance method - this / other // 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 + public Rational divide(Rational other) + { + 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 - public static Rational divide(Rational r1, Rational r2) { - // YOUR CODE HERE - return null; // Remove this line when implemented + // Static method - r1 / r2 + public static Rational divide(Rational r1, Rational r2) + { + return r1.divide(r2); } // PROVIDED - String representation @Override - public String toString() { - if (denominator == 1) { + public String toString() + { + if (denominator == 1) return numerator + ""; - } + return numerator + "/" + denominator; } // PROVIDED - Decimal value - public double toDouble() { + public double toDouble() + { return (double) numerator / denominator; } } diff --git a/src/main/java/movie/apis/Genre.java b/src/main/java/movie/apis/Genre.java index 8560f7f..cbac218 100644 --- a/src/main/java/movie/apis/Genre.java +++ b/src/main/java/movie/apis/Genre.java @@ -1,35 +1,41 @@ package movie.apis; -public class Genre { +public class Genre +{ private Long id; private String name; - public Genre(Long id, String name) { + public Genre(Long id, String name) + { this.id = id; this.name = name; } - public Genre() { - } + public Genre() {} - public Long getId() { + public Long getId() + { return id; } - public void setId(Long id) { + public void setId(Long id) + { this.id = id; } - public String getName() { + public String getName() + { return name; } - public void setName(String name) { + public void setName(String name) + { this.name = name; } @Override - public String toString() { + public String toString() + { return id + ". " + name; } } \ No newline at end of file diff --git a/src/main/java/movie/apis/Main.java b/src/main/java/movie/apis/Main.java index f0e713d..ea0aed4 100644 --- a/src/main/java/movie/apis/Main.java +++ b/src/main/java/movie/apis/Main.java @@ -2,57 +2,70 @@ package movie.apis; import java.util.Scanner; -public class Main { - +public class Main +{ private static final MovieService movieService = new MovieService(); private static final Scanner scanner = new Scanner(System.in); - public static void main(String[] args) { + public static void main(String[] args) + { System.out.println("\n=== MOVIE API CLIENT ===\n"); boolean running = true; - while (running) { + while (running) + { displayMenu(); int choice = getIntInput("Enter your choice: "); - switch (choice) { + switch (choice) + { case 1: + { movieService.displayGenres(); break; + } case 2: - // TODO: Get genre ID and page from user, then call movieService.displayMoviesByGenre() + { + long GenreId = getLongInput("Enter genre ID: "); + long PageNumber = getLongInput("Enter page number: "); + movieService.displayMoviesByGenre(GenreId, PageNumber); 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: + { running = false; System.out.println("Goodbye!"); break; + } default: System.out.println("Invalid choice! Please enter 0-4"); } - if (running) { + if (running) + { System.out.println("\nPress Enter to continue..."); scanner.nextLine(); - scanner.nextLine(); } } scanner.close(); } - private static void displayMenu() { + private static void displayMenu() + { System.out.println("\n================================"); System.out.println(" MENU"); System.out.println("================================"); @@ -63,7 +76,8 @@ public class Main { System.out.println("================================"); } - private static int getIntInput(String prompt) { + private static int getIntInput(String prompt) + { System.out.print(prompt); while (!scanner.hasNextInt()) { System.out.print("Invalid input. " + prompt); @@ -74,7 +88,8 @@ public class Main { return input; } - private static Long getLongInput(String prompt) { + private static Long getLongInput(String prompt) + { System.out.print(prompt); while (!scanner.hasNextLong()) { System.out.print("Invalid input. " + prompt); diff --git a/src/main/java/movie/apis/Movie.java b/src/main/java/movie/apis/Movie.java index c8cc4e2..42987bc 100644 --- a/src/main/java/movie/apis/Movie.java +++ b/src/main/java/movie/apis/Movie.java @@ -6,19 +6,292 @@ import java.util.List; * Model class representing a movie * Fields: id, title, genres, images */ -public class Movie { - +public class Movie +{ private Long id; private String title; - private List genres; - private String images; private String year; - private String imdbRating; + private String imdb_id; + private String imdb_rating; + private String metascore; + private String imdb_votes; // Moved closer to ratings + private String poster; + private List images; + private String plot; + private List genres; + private String director; + private String writer; + private String actors; private String country; + private String released; + private String runtime; + private String rated; + private String awards; + private String type; - // TODO: Create a constructor with all fields + // constructor with all fields + public Movie(Long id, + String title, + List genres, + List images, + String year, + String imdb_rating, + String poster, + String country) + { + this.id = id; + this.title = title; + this.genres = genres; + this.images = images; + this.year = year; + this.imdb_rating = imdb_rating; + this.poster = poster; + this.country = country; + } - // TODO: Create a simple constructor with id and title only + // simple constructor with id and title only + public Movie(Long id, String title) + { + this.id = id; + this.title = title; + } - // TODO: Create getters and setters for all fields + // getters and setters for all fields + public void setWriter(String writer) + { + this.writer = writer; + } + + public void setType(String type) + { + this.type = type; + } + + public void setRuntime(String runtime) + { + this.runtime = runtime; + } + + public void setReleased(String released) + { + this.released = released; + } + + public void setRated(String rated) + { + this.rated = rated; + } + + public void setPlot(String plot) + { + this.plot = plot; + } + + public void setMetascore(String metascore) + { + this.metascore = metascore; + } + + public void setImdb_votes(String imdb_votes) + { + this.imdb_votes = imdb_votes; + } + + public void setImdb_id(String imdb_id) + { + this.imdb_id = imdb_id; + } + + public void setDirector(String director) + { + this.director = director; + } + + public void setAwards(String awards) + { + this.awards = awards; + } + + public void setActors(String actors) + { + this.actors = actors; + } + + public void setId(Long id) + { + this.id = id; + } + + public void setTitle(String title) + { + this.title = title; + } + + public void setGenres(List genres) + { + this.genres = genres; + } + + public void setImages(List images) + { + this.images = images; + } + + public void setPoster(String poster) + { + this.poster = poster; + } + + public void setYear(String year) + { + this.year = year; + } + + public void setImdb_rating(String imdb_rating) + { + this.imdb_rating = imdb_rating; + } + + public void setCountry(String country) + { + this.country = country; + } + + public String getWriter() + { + return writer; + } + + public String getType() + { + return type; + } + + public String getRuntime() + { + return runtime; + } + + public String getReleased() + { + return released; + } + + public String getRated() + { + return rated; + } + + public String getPlot() + { + return plot; + } + + public String getImdb_votes() + { + return imdb_votes; + } + + public String getMetascore() + { + return metascore; + } + + public String getImdb_id() + { + return imdb_id; + } + + public String getDirector() + { + return director; + } + + public String getAwards() + { + return awards; + } + + public String getActors() + { + return actors; + } + + public Long getId() + { + return id; + } + + public String getTitle() + { + return title; + } + + public List getGenres() + { + return genres; + } + + public List getImages() + { + return images; + } + + public String getYear() + { + return year; + } + + public String getImdb_rating() + { + return imdb_rating; + } + + public String getPoster() + { + return poster; + } + + public String getCountry() + { + return country; + } + + @Override + public String toString() + { + StringBuilder MovieInfo = new StringBuilder(); + + MovieInfo.append("=-=-=-=-= Movie Information: =-=-=-=-=\n"); + MovieInfo.append("- Title: ").append(title).append("\n"); + MovieInfo.append("- Year: ").append(year).append("\n"); + MovieInfo.append("- Runtime: ").append(runtime).append("\n"); + MovieInfo.append("- Rated: ").append(rated).append("\n"); + MovieInfo.append("- Released: ").append(released).append("\n"); + MovieInfo.append("- IMDB Rating: ").append(imdb_rating).append("/10 (").append(imdb_votes).append(" votes)\n"); + MovieInfo.append("- Metascore: ").append(metascore).append("/100\n"); + MovieInfo.append("\n"); + + MovieInfo.append("- Director(s): ").append(director).append("\n"); + MovieInfo.append("- Writer(s): ").append(writer).append("\n"); + MovieInfo.append("- Actor(s): ").append(actors).append("\n"); + MovieInfo.append("\n"); + + MovieInfo.append("- Genres: ").append(String.join(",", genres)).append("\n"); + MovieInfo.append("- Plot: ").append(plot).append("\n"); + MovieInfo.append("\n"); + + MovieInfo.append("- Country: ").append(country).append("\n"); + MovieInfo.append("- Awards: ").append(awards).append("\n"); + MovieInfo.append("\n"); + + if (!images.isEmpty()) + { + MovieInfo.append("- Screenshot(s):\n"); + for (String ss : images) + MovieInfo.append(" - ").append(ss).append("\n"); + } + + return MovieInfo.toString(); + } } \ 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 cbbe70b..c964d8d 100644 --- a/src/main/java/movie/apis/MovieService.java +++ b/src/main/java/movie/apis/MovieService.java @@ -4,6 +4,7 @@ import com.google.gson.*; import com.google.gson.reflect.TypeToken; import java.io.IOException; +import java.net.HttpURLConnection; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -12,65 +13,74 @@ import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; -public class MovieService { - +public class MovieService +{ private final static String GENRES_URL = "https://api.meshcomp.ir/api/v1/genres"; private final static String MOVIE_BY_ID_URL = "https://api.meshcomp.ir/api/v1/movies/"; private final static HttpClient client = HttpClient.newHttpClient(); - private String getGenresList() { - try { - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(GENRES_URL)) - .build(); + private String getGenresList() + { + try + { + HttpRequest request = HttpRequest.newBuilder().uri(URI.create(GENRES_URL)).build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - if (response.statusCode() == 200) { + if (response.statusCode() == 200) + { System.out.println("Genres List received successfully"); return response.body(); - } else { - throw new IOException("HTTP error code: " + response.statusCode()); } - } catch (Exception e) { + else + throw new IOException("HTTP error code: " + response.statusCode()); + } + catch (Exception e) + { System.out.println("!!Exception : " + e.getMessage()); } + return null; } - private String getMoviesByGenreList(Long genreId, Long page) { - try { + private String getMoviesByGenreList(Long genreId, Long page) + { + try + { String url = "https://api.meshcomp.ir/api/v1/genres/" + genreId + "/movies?page=" + page; - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .build(); + HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - if (response.statusCode() == 200) { + if (response.statusCode() == 200) return response.body(); - } else { + else + { System.out.println("HTTP error code: " + response.statusCode()); return null; } - } catch (Exception e) { + } + catch (Exception e) + { System.out.println("!!Exception : " + e.getMessage()); } + return null; } - - - public void displayGenres() { + public void displayGenres() + { String jsonResponse = getGenresList(); - if (jsonResponse == null) { + if (jsonResponse == null) + { System.out.println("Failed to get genres"); return; } - try { + try + { JsonObject rootObject = JsonParser.parseString(jsonResponse).getAsJsonObject(); JsonArray genresArray = rootObject.getAsJsonArray("genres"); Type genreListType = new TypeToken>(){}.getType(); @@ -78,17 +88,19 @@ public class MovieService { List genres = gson.fromJson(genresArray, genreListType); System.out.println("\nALL GENRES:"); - for (Genre genre : genres) { + for (Genre genre : genres) System.out.println(genre.getId() + ". " + genre.getName()); - } + System.out.println(); - } catch (Exception e) { + } + catch (Exception e) + { System.err.println("ERROR parsing genres: " + e.getMessage()); } } /** - * TODO 1: Display movies for a specific genre and page + * Display movies for a specific genre and page * * JSON format: { "movies": [ { "id": 1, "title": "Movie", "year": "1994" } ], "total": 177, "total_pages": 18 } * @@ -101,13 +113,30 @@ public class MovieService { * * 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 + public void displayMoviesByGenre(Long genreId, Long page) + { + try + { + String RawData = getMoviesByGenreList(genreId, page); + if (RawData == null) + throw new IllegalArgumentException("Invalid genreId or page number; no data found"); - } catch (Exception e) { + JsonObject JsonData = JsonParser.parseString(RawData).getAsJsonObject(); + JsonArray MoviesArray = JsonData.getAsJsonArray("movies"); + Type MovieListType = new TypeToken>(){}.getType(); + Gson GsonHandle = new Gson(); + List Movies = GsonHandle.fromJson(MoviesArray, MovieListType); + + System.out.printf("\nMovies with %s genre:\n", JsonData.getAsJsonObject("genre").get("name").getAsString()); + for (Movie CurrentMovie : Movies) + System.out.printf("ID: %d | %s (%s)\n", CurrentMovie.getId(), CurrentMovie.getTitle(), CurrentMovie.getYear()); + + System.out.printf("\nTotal: %s - Total pages: %s", JsonData.get("total").getAsString(), JsonData.get("total_pages").getAsString()); + + System.out.println(); + } + catch (Exception e) + { System.err.println("ERROR: " + e.getMessage()); } } @@ -117,18 +146,25 @@ public class MovieService { * 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(); + private String getMovieById(Long movieId) + { + try + { + final String URL = MOVIE_BY_ID_URL + movieId; + + HttpRequest Request = HttpRequest.newBuilder().uri(URI.create(URL)).build(); + HttpResponse Respone = client.send(Request, HttpResponse.BodyHandlers.ofString()); + + if (Respone.statusCode() == HttpURLConnection.HTTP_OK) + return Respone.body(); return null; - } catch (Exception e) { + } + catch (Exception e) + { System.out.println("!!Exception : " + e.getMessage()); } + return null; } @@ -158,30 +194,29 @@ public class MovieService { * * @param movieId The ID of the movie to display */ - public void displayMovieDetails(Long movieId) { - // Step 1: Get JSON response from API + public void displayMovieDetails(Long movieId) + { String jsonResponse = getMovieById(movieId); - // Step 2: Check if we got valid data - if (jsonResponse == null) { + if (jsonResponse == null) + { System.out.println("Failed to get movie details for ID: " + movieId); return; } - // Step 3-6: Parse JSON and display details (PUT YOUR CODE INSIDE try-catch) - try { - // TODO: Parse jsonResponse to JsonObject - // TODO: Extract id, title, year, genres array, poster, country, imdb_rating - // TODO: Convert genres array to a readable string - // TODO: Print all movie details - // HINT: Use JsonParser.parseString(jsonResponse).getAsJsonObject() - // HINT: Use getAsJsonArray("genres") to get genres - // HINT: For each genre, use getAsString() + try + { + JsonObject JsonData = JsonParser.parseString(jsonResponse).getAsJsonObject(); - // Your code here: + Gson GsonHandle = new Gson(); + Type MovieType = new TypeToken(){}.getType(); + Movie RequestedMovie = GsonHandle.fromJson(JsonData, MovieType); - - } catch (Exception e) { + System.out.println(); + System.out.println(RequestedMovie); + } + catch (Exception e) + { System.err.println("ERROR parsing movie details: " + e.getMessage()); } } -- 2.54.0