Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C17 - Celina #121

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Conversation

ArmchairGraduate
Copy link

wave 1,2,3 passing

Copy link

@anselrognlie anselrognlie left a comment

Choose a reason for hiding this comment

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

Good job getting your first project in!

Most of your tests are passing, and overall I'm seeing good thinking about code structure and naming. And great use of set functions for working with the unique movies! Nice job!

It looks like you started to get a little tripped on on the logic in wave 4. We can implement the wave 4 and 5 functions by duplicating a lot of logic from wave 3, but that makes those functions quite long, complex, and difficult to think about. Look for similarities in the function descriptions to the wave 3 functions and think about whether we can reuse any of them to make the later functions a little easier to approach!

Overall, this is heading in the right direction.


assert len(updated_data["watchlist"]) == 0
assert len(updated_data["watched"]) == 1
assert updated_data["watched"][0]["title"] == MOVIE_TITLE_1

Choose a reason for hiding this comment

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

👍


assert len(updated_data["watchlist"]) == 1
assert len(updated_data["watched"]) == 2
assert movie_to_watch in updated_data["watched"]

Choose a reason for hiding this comment

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

👍

@@ -5,5 +5,5 @@ pluggy==0.13.1
pprintpp==0.4.0
py==1.10.0
pyparsing==2.4.7
pytest==6.2.1
pytest==6.2.5

Choose a reason for hiding this comment

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

👍

Keep an eye out for this on your future python projects as well.

Comment on lines +57 to +59
assert FANTASY_4 in friends_unique_movies
assert HORROR_1 in friends_unique_movies
assert INTRIGUE_3 in friends_unique_movies

Choose a reason for hiding this comment

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

👍

Comment on lines +4 to +5
from logging.handlers import WatchedFileHandler
from tkinter import W

Choose a reason for hiding this comment

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

Be careful of VSCode importing stray libraries. When we autocomplete suggestions from VSCode, sometimes we accidentally pick a recommendation to use something not in our code (usually from a typo). When that happens, VSCode might think that it needs to import a library if the suggestion refers to a library not in our code. Even if we fix the typo, the imports will remain! So keep an eye on the import statements, and make sure to remove any that don't look familiar.

Comment on lines 72 to 74
fantasy_count = 0
action_count = 0
intrigue_count = 0

Choose a reason for hiding this comment

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

We should not assume that these are the only possible genres. In the existing data (though not in this test) we've also seen horror films, and there could be others (romcom, thriller, comedy, childrens, etc). So we want to be able to tally up the count of each genre regardless of how many distinct genre values there are.

What data structure lets us store something like the genre (a string) along with a value (the count of that genre)? And how could the logic below be rewritten to make use of it?

Comment on lines +120 to +123
for unique_movie in user_unique_watched_set:
for movie in user_data["watched"]:
if movie["title"] == unique_movie:
user_unique_watched_list.append(movie)

Choose a reason for hiding this comment

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

Since we have a set of unique titles, we can make use of its very efficient membership lookup to avoid the nested loop here. Something like

    for movie in user_data["watched"]:
        if movie["title"] in user_unique_watched_set:
            user_unique_watched_list.append(movie)

If we were concerned that there may have been duplicates within the user's own list, we could remove each title we match from the set so that it only gets used once:

    for movie in user_data["watched"]:
        if movie["title"] in user_unique_watched_set:
            user_unique_watched_list.append(movie)
            user_unique_watched_set.remove(move["title"])


user_watched_set = set(user_watched_list)
friend_watched_set = set(friend_watched_list)
user_unique_watched_set = user_watched_set.difference(friend_watched_set)

Choose a reason for hiding this comment

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

Great use of set operations. Since sets only allow immutable data, we had to use a unique(ish) immutable part of a move to stand in for the whole record.

Comment on lines +143 to +148
for unique_movie in friend_unique_watched_set:
for friend in user_data["friends"]:
for movie in friend["watched"]:
if movie not in friend_unique_watched_list:
if movie["title"] == unique_movie:
friend_unique_watched_list.append(movie)

Choose a reason for hiding this comment

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

The general approach looks fine, but you're right, we could turn this around a bit, similar to get_unique_watched above.

    for friend in user_data["friends"]:
        for movie in friend["watched"]:
            if movie["title"] in friend_unique_watched_set:
                friend_unique_watched_list.append(movie)
                friend_unique_watched_set.remove(movie["title"])

# -----------------------------------------
# ------------- WAVE 4 --------------------
# -----------------------------------------

def get_available_recs(user_data):
friend_watched_movie_title_list = []

Choose a reason for hiding this comment

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

It looks like a lot of the logic here is similar to the get unique methods from wave 3. Can we reuse those functions to help simplify the implementation here? Part of the description says that the recommendations should be things the user hasn't watched, but that at least one friend has watched. Does that sound like the results of one of the wave 3 functions?

Copy link

@anselrognlie anselrognlie left a comment

Choose a reason for hiding this comment

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

Thanks for updating this. Looks good! Take a look at the comments throughout for additional pointers to start thinking about in future projects!

Comment on lines +56 to +59
recommendations = get_new_rec_by_genre(sonyas_data)

# Assert
assert len(recommendations) == 0

Choose a reason for hiding this comment

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

👍


return watched_avg_rating

def get_most_watched_genre(user_data):

Choose a reason for hiding this comment

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

👍

# -----------------------------------------
# ------------- WAVE 4 --------------------
# -----------------------------------------

def get_available_recs(user_data):

Choose a reason for hiding this comment

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

👍

Comment on lines +176 to +177
most_watched_genre = get_most_watched_genre(user_data)
friend_unique_watched = get_friends_unique_watched(user_data)

Choose a reason for hiding this comment

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

👍

Double function reuse!

Comment on lines +162 to +165
for movie in friends_unique_watched_list:
for subscription in user_data["subscriptions"]:
if subscription == movie["host"]:
available_recommended_movies_list.append(movie)

Choose a reason for hiding this comment

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

Looking for the movie host in the subscriptions could be written like this:

    for movie in friends_unique_watched_list:
        if movie["host"] in user_data["subscriptions"]:
            available_recommended_movies_list.append(movie)

This is exactly equivalent to your version, but replaces the explicit loop with an in check expressing the intent of seeing whether the host is in the subscriptions. The other thing this lets us think about doing is possibly calculate a set of the subscriptions and use that for the in check instead. in checks on sets are much more efficient than for lists, so often, if we have a list that we're making in checks on (especially if it's in a loop) we might consider reorganizing the list as a set for improved performance:

    subscription_set = set(user_data["subscriptions"])
    for movie in friends_unique_watched_list:
        if movie["host"] in subscription_set:
            available_recommended_movies_list.append(movie)

This version only needs to iterate once to make the set (outside the loop) a d the inside the loop, it uses fast in checks.

recommended_movies = []

for movie in friend_unique_watched:
if movie not in recommended_movies and movie["genre"] == most_watched_genre:

Choose a reason for hiding this comment

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

Here, recommended_movies is a list because we want to generate a list of movies for the result. We can't simply make it a set, since dictionaries can't go in a set. But much like your "unique" methods from wave 3, we could make a set of movie titles! Before adding a movie to the result, check whether its title is in the title set. Then if not, add the movie to the result and its title to the title set!

recommended_movies.append(movie)
return recommended_movies

def get_rec_from_favorites(user_data):

Choose a reason for hiding this comment

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

👍

There are a few in checks here which we could think about addressing either by reorganizing the order of the looping, or by making helper sets of titles as described above.

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.

2 participants