-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathCMDbProfile.java
432 lines (408 loc) · 18.7 KB
/
CMDbProfile.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
import java.util.ArrayList;
/**
* A class that represents and performs the functions of a CMDbProfile
*
* @author David Nguyen
* @since 04/02/2023
* @version 1.0
*/
public class CMDbProfile {
// Field that represents the profile's username
private String userName;
// Field that stores the profile's number of ratings
private int numberOfRatings;
// Field that stores the movies that this profile has rated
private ArrayList<Movie> moviesArrayList;
/**
* A constructor that constructs a CMDbProfile with the given username.
* Time Complexity: O(1)
*
* @param userName The name of this CMDbProfile
*/
public CMDbProfile(String userName) {
// Initialize the necessary fields
this.userName = userName;
this.numberOfRatings = 0;
this.moviesArrayList = new ArrayList<Movie>();
}
/**
* A method that changes this profile’s existing username to the specified new username.
* Time Complexity: O(1)
*
* @param userName The specified new username
*/
public void changeUserName(String userName) {
this.userName = userName;
}
/**
* A method that adds a rating for the specified movie to this CMDb profile. Assuming that the movie has not existed
* in the database.
* Time Complexity: O(log M) average case, O(M) worst case, where M is the number of movies in the database.
*
* @param movieName Name of the movie to be rated.
* @param rating The rating of the movie, from 1 to 10.
* @return True or False depending on whether the movie has been successfully rated.
*/
public boolean rate(String movieName, int rating) {
// Variable that stores the new movie to be rated and added to the database
Movie newMovie = new Movie(movieName, rating);
// Variable to check if the rating is valid
boolean checkRatingValid;
// If rating is not in the range from 1-10, set the variable to false
if (rating < 1 || rating > 10) {
checkRatingValid = false;
}
// Otherwise, sets the variable to true
else {
checkRatingValid = true;
}
// If rating is invalid, return false immediately
if (checkRatingValid == false) {
return false;
}
// A loop that loops through the movie list to find if there is any existing movie of the same name in the database
for (Movie movie : this.moviesArrayList) {
// If so, return false immediately
if (movie.equals(newMovie)) {
return false;
}
}
// Now, set the rating for the movie, add the new movie to the database, and increment the number of ratings
newMovie.setRatingOfMovie(rating);
this.moviesArrayList.add(newMovie);
this.numberOfRatings = this.numberOfRatings + 1;
// Return true to indicate that the rating process has completed successfully
return true;
}
/**
* A method that changes the existing rating for the specified movie to the specified new rating for this CMDb profile.
* Time Complexity: O(M) worst case, where M is the number of movies in the database.
*
* @param movie Any movie to be changed rating.
* @param newRating The new rating for the movie.
* @return True or False depending on whether the rating of the movie has been successfully changed.
*/
public boolean changeRating(String movie, int newRating) {
// Variable to store whether the rating has been successfully changed
boolean ratingChanged = false;
// Variable to check whether the new rating is valid
boolean checkRatingValid;
// If rating is not in the range from 1-10, set the variable to false
if (newRating < 1 || newRating > 10) {
checkRatingValid = false;
}
// Otherwise, sets the variable to true
else {
checkRatingValid = true;
}
// If rating is invalid, return false immediately
if (checkRatingValid == false) {
return false;
}
// A loop that loops through the movie list to find the existing movie of the same name in the database
for (Movie tempMovie : this.moviesArrayList) {
// Variable that stores the name of the current movie being iterated through
String nameOfTempMovie = tempMovie.getNameOfMovie();
// If the same movie is found, change its rating to the new rating
if (nameOfTempMovie.equals(movie)) {
tempMovie.setRatingOfMovie(newRating);
// Indicate that the rating process has completed successfully and break the loop
ratingChanged = true;
break;
}
}
// Indicate that the rating process has completed either successfully or unsuccessfully
return ratingChanged;
}
/**
* A method that removes the movie and its corresponding rating from the database.
* If the specified movie does not exist in the database, return false. Otherwise, return true.
* Time Complexity: O(M) worst case, where M is the number of movies in the database
*
* @param movie The movie to be deleted from the database.
* @return If the specified movie does not exist in the database, return false. Otherwise, return true.
*/
public boolean removeRating(String movie) {
// Variable to store whether the rating has been successfully changed and whether the movie has been successfully removed
boolean ratingAndMovieRemoved = false;
// A loop that loops through the movie list to find the existing movie of the same name in the database
for (Movie tempMovie : this.moviesArrayList) {
// Variable that stores the name of the current movie being iterated through
String nameOfTempMovie = tempMovie.getNameOfMovie();
if (nameOfTempMovie.equals(movie)) {
// Remove the movie from the database and decrement the number of ratings by 1
this.moviesArrayList.remove(tempMovie);
this.numberOfRatings = this.numberOfRatings - 1;
// Indicate that the remove rating and movie process has completed successfully & break the loop
ratingAndMovieRemoved = true;
break;
}
}
// Indicate that the rating process has completed either successfully or unsuccessfully by returning true or false
if (ratingAndMovieRemoved == true) {
return true;
}
else {
return false;
}
}
/**
* A method that returns all the user’s movies with the highest rating given by the user.
* If this CMDb profile does not have any ratings yet, you should return null.
* Time Complexity: O(1)
*
* @return A strings array containing all the user’s movies with the highest rating given by the user. Null if the
* user has not had any ratings yet.
*/
public String[] favorite() {
// A temporary ArrayList to store the favorite movies of this profile
ArrayList<Movie> favoriteMoviesList = new ArrayList<Movie>();
// Variable to store the number's maximum (highest) rating
int maximumRatingByUser = 0;
// Variable to store the rating of the current movie being looped through
int ratingOfCurrentMovie = 0;
// If the number of ratings is 0, return null
if (this.numberOfRatings == 0) {
return null;
}
// Else, ignore it and let the method continue as normal
else {
;
}
/* A loop that iterates through the movies array list to find if there is any movie with the rating higher than
* the current max rating by the profile. */
for (Movie tempMovie : this.moviesArrayList) {
// Update the variable to store the rating of the current movie being looped through
ratingOfCurrentMovie = tempMovie.getRatingOfMovie();
// If the rating of the current movie is greater than the current highest rating, add it to the favorite movies list
if (ratingOfCurrentMovie > maximumRatingByUser) {
favoriteMoviesList.clear();
favoriteMoviesList.add(tempMovie);
// Sets the maximum rating variable accordingly
maximumRatingByUser = tempMovie.getRatingOfMovie();
}
// If the rating of the current movie is smaller than the maximum rating by the user, do nothing and ignore it
else if (ratingOfCurrentMovie < maximumRatingByUser) {
;
}
// If the rating of the current movie is equal to the maximum rating by the user, also add the movie to the list
else if (ratingOfCurrentMovie == maximumRatingByUser) {
favoriteMoviesList.add(tempMovie);
}
}
// Variable to store the number of favorite movies currently in the list
int numFavoriteMovies = favoriteMoviesList.size();
// Variable to store the favorite movies to be returned later on
String[] favoriteMoviesArray = new String[numFavoriteMovies];
// Loops through the two arrays and lists to copy the items over and return the array of strings
for (int i = 0; i < numFavoriteMovies; i = i + 1) {
// Variable to store the current favorite movie in the favorite movies list
Movie favoriteMovie = favoriteMoviesList.get(i);
// Variable to store its respective name
String nameOfFavorite = favoriteMovie.getNameOfMovie();
// Copy its name over to the array
favoriteMoviesArray[i] = nameOfFavorite;
}
// Return the above-mentioned array
return favoriteMoviesArray;
}
/**
* A method that returns the user’s k highest-rated movies.
* Time Complexity: O(k log M), where M is the number of movies in the database.
* Space Complexity: O(k)
*
* @param k The number to find the k highest-rated movies.
* @return An array of the user's k highest-rated movies.
*/
public String[] favorite(int k) {
// If there is currently no ratings from the profile, return an empty array
if (this.numberOfRatings == 0) {
// an empty array to be returned
String[] returnArray = new String[0];
return returnArray;
}
// Variable to store the current favorite movies list
ArrayList<String> favoriteMoviesList = new ArrayList<String>();
// Variable to store the current movies list in the database
ArrayList<Movie> currentMovieList = new ArrayList<Movie>(this.moviesArrayList);
// Variable to store the current count of movies in the list
int countOfMovies = 0;
// Loops through the current movies list to find the k highest-rated movies
while (countOfMovies != k && currentMovieList.isEmpty() == false) {
// Create a variable to memorize the last-state index when looping
int lastIndex = 0;
// Loops through the current movies list to get the k highest-rated movies
for (int index = 1; index < currentMovieList.size(); index = index + 1) {
// Variable to store the current movie being looped through
Movie currentMovie = currentMovieList.get(index);
// Variable to store the current rating of the current movie
int currentRating = currentMovie.getRatingOfMovie();
// Variable to store the last movie at the last index
Movie lastMovie = currentMovieList.get(lastIndex);
// Variable to store the last rating of the last movie
int lastMovieRating = lastMovie.getRatingOfMovie();
// If the current movie's rating is greater than the last movie's rating, set the two variables be equal to each other
if (currentRating > lastMovieRating) {
lastIndex = index;
}
}
// Add the movies to the favorite movies list and remove the respective movie from the current movies list
favoriteMoviesList.add(currentMovieList.get(lastIndex).getNameOfMovie());
currentMovieList.remove(lastIndex);
// Increment count of movies
countOfMovies = countOfMovies + 1;
}
// At the end of the loop, create a new variable to store the favorite movies list as an array of strings then return it
String[] returnArray = favoriteMoviesList.toArray(new String[0]);
return returnArray;
}
/**
* A method that returns a String containing the profile information for this CMDb profile.
* Time Complexity: O(1)
*
* @return a String containing the profile information for this CMDb profile.
*/
public String profileInformation() {
// A StringBuilder to build the profile information for this CMDb profile.
StringBuilder profileInformation = new StringBuilder();
// Array to store the favorite movies array of this CMDb profile.
String[] favoriteMoviesArray = favorite();
// Variable to get one of the user's favorite movie.
String favoriteMovie = new String();
// If this user has no ratings, handle the case differently by stating that he/she currently has no ratings
if (this.numberOfRatings == 0) {
// Variable to store the profile information
String profile = new String(this.userName + " (" + this.numberOfRatings + ")\nFavorite Movie: NO RATINGS YET!");
// Append it to the StringBuilder instance and then return it
profileInformation.append(profile);
return profileInformation.toString();
}
if (favoriteMoviesArray.length != 0 && this.numberOfRatings != 0) {
// Take a favorite movie from the favorite movies array
favoriteMovie = favoriteMoviesArray[0];
// Variable to store the profile information
String profile = new String (this.userName + " (" + this.numberOfRatings + ")\nFavorite Movie: " + favoriteMovie);
// Append it to the StringBuilder instance and then return it
profileInformation.append(profile);
}
return profileInformation.toString();
}
/**
* A method that returns true if this profile’s username is the same as the specified Object’s username and if it is also
* a CMDb profile. Otherwise, return false.
* Time complexity: O(A+B), where A is the number of characters in this profile’s username and B is the number of
* characters in the specified profile’s username.
*
* @param o The object to be passed into this method
* @return true if this profile’s username is the same as the specified Object’s username and if it is also
* a CMDb profile. Otherwise, return false.
*/
@Override
public boolean equals(Object o) {
// Variable to store the return state
boolean returnValue = false;
// If o is an instance of CMDbProfile, cast it to CMDbProfile and then check if its username is equal to this username
if (o instanceof CMDbProfile) {
// Cast o to CMDbProfile
CMDbProfile cmDbProfile = (CMDbProfile) o;
// If o's username is equal to this username, set return value to true
if (this.userName.equals(cmDbProfile.userName)) {
returnValue = true;
}
// Else, set it to false
else {
returnValue = false;
}
}
// Otherwise, if o is not an instance of CMDbProfile, set it to false,
else {
returnValue = false;
}
// Return true or false depending on the above conditions
return returnValue;
}
/**
* A method that return this CMDbProfile's username.
* Time Complexity: O(1)
*
* @return This CMDbProfile's username
*/
protected String getUserName() {
return this.userName;
}
/**
* A method that checks whether the movie has been rated by a CMDbProfile.
* Time Complexity: O(N) where N is the max number of movies in the list.
*
* @param movie The movie to check
* @return True or false depending on whether the movie has been rated by a CMDbProfile.
*/
protected boolean hasRated(String movie) {
// Variable to store whether the movie has been rated by a CMDbProfile
boolean hasRated = false;
// Loops through the movies array list to see whether the movie has been rated
for (Movie tempMovie : this.moviesArrayList) {
// Variable to store the name of the current movie being looped through
String nameOfTempMovie = tempMovie.getNameOfMovie();
// If there is any matching movies, return true and break the loop
if (nameOfTempMovie.equals(movie)) {
hasRated = true;
break;
}
}
// Return true or false depending on whether the movie has been rated by a CMDbProfile.
return hasRated;
}
/**
* A class that stores and represents a Movie in the Case Movie Data Base
*
* @author David Nguyen
* @since 04/02/2023
* @version 1.0
*/
private class Movie {
// Field to store the name of the movie
private String nameOfMovie;
// Field to store the rating of the movie
private int ratingOfMovie;
/**
* A constructor that creates a movie with the specified name and rating.
* Time Complexity: O(1)
*
* @param nameOfMovie Specified name to create a movie with
* @param ratingOfMovie Specified rating to create a movie with
*/
protected Movie(String nameOfMovie, int ratingOfMovie) {
// Initialize the necessary variable
this.nameOfMovie = nameOfMovie;
this.ratingOfMovie = ratingOfMovie;
}
/**
* A method that returns the name of the movie.
* Time Complexity: O(1)
*
* @return The name of this movie
*/
protected String getNameOfMovie() {
return this.nameOfMovie;
}
/**
* A method that returns the rating of the movie.
* Time Complexity: O(1)
*
* @return The rating of this movie
*/
protected int getRatingOfMovie() {
return this.ratingOfMovie;
}
/**
* A method that sets the rating of the movie.
* Time Complexity: O(1)
*
* @param ratingOfMovie The rating of this movie
*/
protected void setRatingOfMovie(int ratingOfMovie) {
this.ratingOfMovie = ratingOfMovie;
}
}
}