import bisect class RecentList: def __init__(self): # Initialize dictionaries to store titles and associated data self.films = {} self.series = {} # Initialize lists to keep track of the sorted entries self.sorted_films = [] self.sorted_series = [] def add_entry(self, title, year, description, image_link, media_type): if media_type == 'film': self._update_entry(self.films, self.sorted_films, title, year, description, image_link) elif media_type == 'series': self._update_entry(self.series, self.sorted_series, title, year, description, image_link) def _update_entry(self, dictionary, sorted_list, title, year, description, image_link): try: # Convert year to integer year = int(year) except ValueError: raise ValueError(f"Invalid year: {year}. Year must be an integer.") if title in dictionary: # Remove the old entry from the sorted list if it exists old_year = dictionary[title][0] # Get the old year try: sorted_list.remove((-old_year, title)) except ValueError: pass # Ignore if the old entry does not exist in the sorted list # Update or add the new entry in the dictionary dictionary[title] = (year, description, image_link) # Insert the new year and title into the sorted list bisect.insort(sorted_list, (-year, title)) def get_sorted_entries(self, media_type): if media_type == 'film': # Get sorted films with details return [(title, -year, self.films[title][1], self.films[title][2]) for year, title in self.sorted_films] elif media_type == 'series': # Get sorted series with details return [(title, -year, self.series[title][1], self.series[title][2]) for year, title in self.sorted_series] import bisect class GenreList: def __init__(self): # Initialize a dictionary to store genres and their associated data self.genres = {} def add_entry(self, genres, title, year, description, image_link, media_type): """ Add an entry to multiple genres. :param genres: A list of genre dictionaries, each containing 'id', 'name', and 'slug'. :param title: The title of the media. :param year: The release year of the media. :param description: A brief description of the media. :param image_link: A URL to an image representing the media. :param media_type: The type of media ('movie' or 'series'). """ for genre in genres: genre_name = genre['name'] if genre_name not in self.genres: # Initialize the genre with an empty dictionary and sorted list self.genres[genre_name] = {'entries': {}, 'sorted_entries': []} # Update or add the entry in the specified genre self._update_genre(self.genres[genre_name]['entries'], self.genres[genre_name]['sorted_entries'], title, year, description, image_link, media_type) def _update_genre(self, dictionary, sorted_list, title, year, description, image_link, media_type): try: # Convert year to integer year = int(year) except ValueError: raise ValueError(f"Invalid year: {year}. Year must be an integer.") if title in dictionary: # Remove the old entry from the sorted list if it exists old_year = dictionary[title][0] # Get the old year try: sorted_list.remove((-old_year, title)) except ValueError: pass # Ignore if the old entry does not exist in the sorted list # Update or add the new entry in the genre dictionary dictionary[title] = (year, description, image_link, media_type) # Insert the new year and title into the sorted list bisect.insort(sorted_list, (-year, title)) def get_sorted_entries(self, genre_name, media_type=None): """ Get sorted entries for a specified genre and optional media type. :param genre_name: The name of the genre to retrieve entries from. :param media_type: Optional. Filter by media type ('movie' or 'series'). :return: A list of tuples containing title, year, description, image_link, and media_type. """ if genre_name in self.genres: entries = [ (title, -year, self.genres[genre_name]['entries'][title][1], self.genres[genre_name]['entries'][title][2], self.genres[genre_name]['entries'][title][3]) for year, title in self.genres[genre_name]['sorted_entries'] ] if media_type: entries = [entry for entry in entries if entry[4] == media_type] return entries else: return [] def get_entries_by_multiple_genres(self, genre_names, media_type=None): """ Get entries that are present in all specified genres. :param genre_names: A list of genre names. :param media_type: Optional. Filter by media type ('movie' or 'series'). :return: A list of tuples containing title, year, description, image_link, and media_type. """ if not genre_names: return [] # Get entries for the first genre common_entries = set(self.genres[genre_names[0]]['entries'].keys()) if genre_names[0] in self.genres else set() # Intersect with entries of the remaining genres for genre_name in genre_names[1:]: if genre_name in self.genres: common_entries.intersection_update(self.genres[genre_name]['entries'].keys()) else: return [] # Collect the sorted entries for the common titles sorted_entries = [] for title in common_entries: year = self.genres[genre_names[0]]['entries'][title][0] description = self.genres[genre_names[0]]['entries'][title][1] image_link = self.genres[genre_names[0]]['entries'][title][2] media_type_entry = self.genres[genre_names[0]]['entries'][title][3] if media_type is None or media_type_entry == media_type: sorted_entries.append((title, year, description, image_link, media_type_entry)) # Sort the entries by year (descending) sorted_entries.sort(key=lambda x: -x[1]) return sorted_entries def remove_genre(self, genre_name): """Remove a genre entirely from the list.""" if genre_name in self.genres: del self.genres[genre_name] def remove_entry_from_genre(self, genre_name, title): """Remove a specific title from a specific genre.""" if genre_name in self.genres and title in self.genres[genre_name]['entries']: old_year = self.genres[genre_name]['entries'][title][0] del self.genres[genre_name]['entries'][title] self.genres[genre_name]['sorted_entries'].remove((-old_year, title)) # Example usage: # genre_list = GenreList() # genres = [ # {"id": 15, "name": "Comedy", "slug": "comedy"}, # {"id": 17, "name": "Animation", "slug": "animation"}, # {"id": 27, "name": "Anime", "slug": "anime"} # ] # genres2 = [ # {"id": 15, "name": "Comedy", "slug": "comedy"}, # {"id": 17, "name": "Animation", "slug": "animation"}, # {"id": 27, "name": "Anime", "slug": "anime"} # ] # genre_list.add_entry(genres, 'Movie Title', 2023, 'Description here', 'image_link_here', 'movie') # genre_list.add_entry(genres2, 'Series Title', 2022, 'Series Description', 'series_image_link_here', 'movie') # # Fetch entries that belong to both 'Comedy' and 'Animation' # sorted_entries = genre_list.get_entries_by_multiple_genres(['Comedy', 'Animation'], media_type='movie') # print(sorted_entries) # This should return only 'Movie Title' which is in both 'Comedy' and 'Animation'