Skip to content

Sphinx - Christelle Nkera and Somy Cho#21

Open
scnkera wants to merge 26 commits intoAda-C22:mainfrom
scnkera:main
Open

Sphinx - Christelle Nkera and Somy Cho#21
scnkera wants to merge 26 commits intoAda-C22:mainfrom
scnkera:main

Conversation

@scnkera
Copy link
Copy Markdown

@scnkera scnkera commented Sep 27, 2024

No description provided.

Comment thread viewing_party/party.py
Comment on lines +4 to +13
movie_dict = {}

if not title or not genre or not rating:
return None
else:
movie_dict['title'] = title
movie_dict['genre'] = genre
movie_dict['rating'] = rating

return movie_dict
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another way of writing this function could be like so:

def create_movie(title, genre, rating):
    if not title or not genre or not rating:
        return None
    
    return {
        "title": title,
        "genre": genre,
        "rating": rating
    }

Since all you are doing is creating a dictionary with the arguments your function is given I would think its okay to not use any variables here.

Comment thread viewing_party/party.py
for movie in user_data["watchlist"]:
if movie["title"] == title:
user_data["watchlist"].remove(movie)
user_data["watched"].append(movie)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we write a function above that does this? 👀

Comment thread viewing_party/party.py
if movie["title"] == title:
user_data["watchlist"].remove(movie)
user_data["watched"].append(movie)
break
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💅🏿

Comment thread viewing_party/party.py

for movie in user_data["watchlist"]:
if movie["title"] == title:
user_data["watchlist"].remove(movie)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So now that we have talked about Big O analysis, we know that .remove has a time complexity of O(n) since it needs to look through every element in a list to find the sought after value. Right now, this loop has an outer loop of O(n) and you when you find the movie to remove you have another O(n) operation. How could we circumvent using remove? (Hint: Think about list comprehension)

Also in this implementation, we will only use remove once, but in other filtering problems we might have to do this for multiple elements so it doesn't hurt to get in the habit now.

Comment thread viewing_party/party.py

average = total_rating / len(user_data["watched"])

return average
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice function, clean and concise!

Comment thread viewing_party/party.py
Comment on lines +54 to +65
genre_count = {"Fantasy": 0, "Intrigue": 0, "Action": 0} #change method so that other genres can be included

if not user_data["watched"]:
return None

for movie in user_data["watched"]:
genre = movie["genre"]
if genre in genre_count:
genre_count[genre] += 1
top_genre = max(genre_count, key=genre_count.get)

return top_genre
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So right now, your code is dependent on if the movie has a genre of one the three listed on line 54. Though it passes the tests, as coders we want to think beyond the tests as well (what is a movie had a genre of romance?). How could we implement a version of this that is agnostic to specific genres? (Hint: Hash Maps/Frequency Maps)

Comment thread viewing_party/party.py
Comment on lines +70 to +87
def get_unique_watched(user_data):

movies_not_watched_by_friends = []

for movie_watched_by_user in user_data["watched"]:
watched_by_any_friend = False

# checks if the movie is has been watched by a friend
for friend in user_data["friends"]:
if movie_watched_by_user in friend["watched"]:
watched_by_any_friend = True
break

# If no friend has watched it, adds it to the final list
if not watched_by_any_friend:
movies_not_watched_by_friends.append(movie_watched_by_user)

return movies_not_watched_by_friends
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job on completing this function! If I could offer a piece a feedback it would be maybe flattening the lists of friends and their lists of watched movies. That way you can just loop over the a master collection of friends' movies instead of looping over the friends and then their list of movies. We could even make the master collection a dict so don't have to loop over that. The implementation could look like this:

def get_unique_watched(user_data):
    user_watched = user_data["watched"]
    friends = user_data["friends"]
    friend_titles = {}
    unique_movies = []

    for friend in friends:
        watched_movies = friend["watched"]
        
        for movie in watched_movies:
            title = movie["title"]
            friend_titles[title] = True
    
    for movie in user_watched:
        title = movie["title"]

        if not friend_titles.get(title):
            unique_movies.append(movie)
    
    return unique_movies

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think the time complexity of implementation like this would be?

Comment thread viewing_party/party.py
if movie not in user_data["watched"] and movie not in movies_watched_by_friends_not_user:
movies_watched_by_friends_not_user.append(movie)

return movies_watched_by_friends_not_user
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feedback from the function above could be applied here as well.

Comment thread viewing_party/party.py

# Populate user_watched set with movie titles from user_data
for movie in user_data.get("watched"):
if "title" in movie:
Copy link
Copy Markdown

@mikellewade mikellewade Sep 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why we check to see if title in the movie keys?

Comment thread viewing_party/party.py
Comment on lines +117 to +121
# Loop through each friend and their watched movies
for friend in user_data.get("friends"):
for movie in friend.get("watched"):
# Only add the movie if it's hosted on a subscribed platform and not watched by the user
if movie["host"] in subscriptions and movie["title"] not in user_watched:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking back at the first requirements of this function, isn't there a function that completes part of them for us? Specifically these two:

Determine a list of recommended movies. A movie should be added to this list if and only if:

  • The user has not watched it
  • At least one of the user's friends has watched
  • ...

This could clear up a lot of the code that we have in this function.

Comment thread viewing_party/party.py
Comment on lines +141 to +146
genre_counter = {}
for movie in watched_movies:
genre = movie["genre"]
if genre not in genre_counter:
genre_counter[genre] = 0
genre_counter[genre] += 1
Copy link
Copy Markdown

@mikellewade mikellewade Sep 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the frequency map concept I was referring to in this comment. Nice work, implementing it here! Though, don't we have a function that does this? 😉

Comment thread viewing_party/party.py
if movie not in recommendations:
recommendations.append(movie)

return recommendations
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how the function could look if we implemented it using functions that we've written before:

Click to reveal Python code
def get_new_rec_by_genre(user_data):
  if not user_data["watched"]:
      return []

  most_watched_genre = get_most_watched_genre(user_data)
  temp_recs = get_available_recs(user_data)
  recs = []

  for movie in temp_recs:
      if movie["genre"] == most_watched_genre:
          recs.append(movie)
  
  return recs

Comment thread tests/test_wave_01.py
Comment on lines +162 to +167
if updated_data["watched"][0] != {
"title": MOVIE_TITLE_1,
"genre": GENRE_1,
"rating": RATING_1
}:
raise Exception("The movie was not moved to the watched.")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How this be rewritten with using an assert statement so that we follow the testing format we use with Arrange, Act, Assert?

@mikellewade
Copy link
Copy Markdown

Great work, Christelle & Somy! Your code was well organized and a pleasure to look through! In general, the feedback you will find will be mainly about recognizing situations where you could use functions that you've already written to in implementations you write later down the road. Also, I would suggest to use variables a bit more often so that you can increase the readability of your code. Keep up the good coding! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants