public IBasicInputForUser AsBasicInput(int minEpisodesWatchedToCount, bool includeDropped, Predicate <int> additionalOkToRecommendPredicate) { Dictionary <int, float> basicRatings = new Dictionary <int, float>(); foreach (KeyValuePair <int, MalListEntry> malListEntry in Entries) { int malAnimeId = malListEntry.Key; MalListEntry entry = malListEntry.Value; // Only use a rating if the user completed the anime or has seen at least N episodes if (entry.Rating != null && ((entry.Status == CompletionStatus.Completed || entry.NumEpisodesWatched >= minEpisodesWatchedToCount) || (includeDropped && entry.Status == CompletionStatus.Dropped))) { basicRatings[malAnimeId] = (float)entry.Rating.Value; } } if (additionalOkToRecommendPredicate == null) { return(new BasicInputForUserWithOkToRecommendPredicate(basicRatings, ItemIsOkToRecommend)); } else { return(new BasicInputForUserWithOkToRecommendPredicate(basicRatings, (itemId) => ItemIsOkToRecommend(itemId) && additionalOkToRecommendPredicate(itemId))); } }
public ClassifiedUserInput <MalUserListEntries> Classify(MalUserListEntries inputForUser) { Dictionary <int, MalListEntry> likedAnimes = new Dictionary <int, MalListEntry>(); Dictionary <int, MalListEntry> unlikedAnimes = new Dictionary <int, MalListEntry>(); Dictionary <int, MalListEntry> otherAnimes = new Dictionary <int, MalListEntry>(); // Dropped anime is automatically considered unliked. // All other anime that is completed or has > N episodes seen gets percentage-classified. List <KeyValuePair <int, MalListEntry> > animesEligibleForPercentageClassification = new List <KeyValuePair <int, MalListEntry> >(); foreach (KeyValuePair <int, MalListEntry> animeIdAndEntry in inputForUser.Entries) { int animeId = animeIdAndEntry.Key; MalListEntry entry = animeIdAndEntry.Value; if (entry.Status == CompletionStatus.Dropped) { unlikedAnimes[animeId] = entry; } else if (entry.Status == CompletionStatus.Completed && entry.Rating != null) { animesEligibleForPercentageClassification.Add(animeIdAndEntry); } else if (entry.NumEpisodesWatched > MinEpisodesToClassifyIncomplete && entry.Rating != null) { animesEligibleForPercentageClassification.Add(animeIdAndEntry); } else { otherAnimes[animeId] = entry; } } PercentageSplit <KeyValuePair <int, MalListEntry> > percentageClassified = RecUtils.SplitByPercentage( animesEligibleForPercentageClassification, GoodFraction, (animeIdAndEntry1, animeIdAndEntry2) => animeIdAndEntry1.Value.Rating.Value.CompareTo(animeIdAndEntry2.Value.Rating.Value)); foreach (KeyValuePair <int, MalListEntry> unlikedAnimeIdAndEntry in percentageClassified.LowerPart) { unlikedAnimes[unlikedAnimeIdAndEntry.Key] = unlikedAnimeIdAndEntry.Value; } foreach (KeyValuePair <int, MalListEntry> likedAnimeIdAndEntry in percentageClassified.UpperPart) { likedAnimes[likedAnimeIdAndEntry.Key] = likedAnimeIdAndEntry.Value; } return(new ClassifiedUserInput <MalUserListEntries>( liked: new MalUserListEntries(ratings: likedAnimes, animes: inputForUser.AnimesEligibleForRecommendation, malUsername: inputForUser.MalUsername, okToRecommendPredicate: inputForUser.OkToRecommendPredicate), notLiked: new MalUserListEntries(ratings: unlikedAnimes, animes: inputForUser.AnimesEligibleForRecommendation, malUsername: inputForUser.MalUsername, okToRecommendPredicate: inputForUser.OkToRecommendPredicate), other: new MalUserListEntries(ratings: otherAnimes, animes: inputForUser.AnimesEligibleForRecommendation, malUsername: inputForUser.MalUsername, okToRecommendPredicate: inputForUser.OkToRecommendPredicate) )); }
public ClassifiedUserInput <MalUserListEntries> Classify(MalUserListEntries inputForUser) { Dictionary <int, MalListEntry> likedAnimes = new Dictionary <int, MalListEntry>(); Dictionary <int, MalListEntry> unlikedAnimes = new Dictionary <int, MalListEntry>(); Dictionary <int, MalListEntry> otherAnimes = new Dictionary <int, MalListEntry>(); // Dropped anime is automatically considered unliked. // All other anime that is completed or has > N episodes seen gets classified by rating // Everything else goes into Other. foreach (KeyValuePair <int, MalListEntry> animeIdAndEntry in inputForUser.Entries) { int animeId = animeIdAndEntry.Key; MalListEntry entry = animeIdAndEntry.Value; if (entry.Status == CompletionStatus.Dropped) { unlikedAnimes[animeId] = entry; } else if (entry.Status == CompletionStatus.Completed && entry.Rating != null) { if (entry.Rating.Value >= MinimumGoodScore) { likedAnimes[animeId] = entry; } else { unlikedAnimes[animeId] = entry; } } else if (entry.NumEpisodesWatched > MinEpisodesToClassifyIncomplete && entry.Rating != null) { if (entry.Rating.Value >= MinimumGoodScore) { likedAnimes[animeId] = entry; } else { unlikedAnimes[animeId] = entry; } } else { otherAnimes[animeId] = entry; } } return(new ClassifiedUserInput <MalUserListEntries>( liked: new MalUserListEntries(ratings: likedAnimes, animes: inputForUser.AnimesEligibleForRecommendation, malUsername: inputForUser.MalUsername, okToRecommendPredicate: inputForUser.OkToRecommendPredicate), notLiked: new MalUserListEntries(ratings: unlikedAnimes, animes: inputForUser.AnimesEligibleForRecommendation, malUsername: inputForUser.MalUsername, okToRecommendPredicate: inputForUser.OkToRecommendPredicate), other: new MalUserListEntries(ratings: otherAnimes, animes: inputForUser.AnimesEligibleForRecommendation, malUsername: inputForUser.MalUsername, okToRecommendPredicate: inputForUser.OkToRecommendPredicate) )); }
public ListEntryAndAnimeId(int animeId, MalListEntry entry) { m_animeId = animeId; m_entry = entry; }