# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

import pandas as pd

dt_links=pd.read_csv("links.csv",encoding="utf-8")
dt_movies=pd.read_csv("movies.csv",encoding="utf-8")
dt_tags=pd.read_csv("tags.csv",encoding="utf-8")
dt_ratings=pd.read_csv("ratings.csv",encoding="utf-8")
parsed_films=pd.read_csv("films_parsed.csv",encoding="utf-8")
user_films=pd.read_csv("users_films.csv",encoding="utf-8")

user_films.pop('userId')

users_films=user_films.copy


# ![vase](wr.png)

# v количество отзывов 
# m минимальное количесчтво отзывов для чарта
# R средний рейтинг фильм
# C средний рейтинг по всем фильмам

def getAverageRatings(users_films, if_user):
    """Funtion calculating average rating by user or for film

    Args:
        users_films (DataFrame): Table with users and films they rated/viewed.
        if_user (bool): this telling us calculate for user/film.

    Returns:
        dict: Avarege rating for each movie or user.

    """

    ax = 1 if if_user else 0
    #axis = 1 means rows and axis = 0 means columns 
    sumOfRatings = users_films.sum(axis = ax).to_numpy() #this will give an array of sum of all the ratings of user if axis = 1 else 
    #sum of all the ratings of movies if axis = 0
    noOfRatings = (users_films!=0).sum(axis = ax).to_numpy()  #this will give a boolean True or False array, and True means 1 and False 
    #means 0, and further we are summing it to get the count of all the non-zero cells means length of non-zero cells
    rows, cols = users_films.shape
    averageRatings = {i: sumOfRatings[i]/noOfRatings[i] for i in range(rows if if_user else cols) if noOfRatings[i]!=0}
    return averageRatings


avg_raring_per_movie = list(getAverageRatings(user_films, False).values())


def Average(lst):
    return sum(lst) / len(lst)


C=Average(avg_raring_per_movie)

dt_ratings_2= dt_ratings.groupby(['movieId']).count()

dt_ratings_2=dt_ratings_2.loc[dt_ratings_2['userId'] > 1]

m=dt_ratings_2['userId'].quantile(0.9)

q_movies = dt_ratings_2.copy().loc[dt_ratings_2['userId'] >= m]

q_movies

avg_raring_per_movie = getAverageRatings(user_films, False)

movies_merged=pd.merge(dt_movies, dt_ratings.groupby(['movieId']).count(), on='movieId', how='inner')

movies_merged=movies_merged.loc[movies_merged['userId'] > 1]

movies_merged['avg']=list(getAverageRatings(user_films, False).values())

len(list(getAverageRatings(user_films, False).values()))

m=movies_merged['userId'].quantile(0.9)

q_movies = movies_merged.copy().loc[movies_merged['userId'] >= m]


def weighted_rating(x, m=m, C=C):
    v = x['userId']
    R = x['avg']
    # Calculation based on the IMDB formula
    return (v/(v+m) * R) + (m/(m+v) * C)


q_movies['score'] = q_movies.apply(weighted_rating, axis=1)


q_movies = q_movies.sort_values('score', ascending=False)


q_movies

q_movies.loc[q_movies['movieId']==7153].index[0]


def find_no_viewed(x,k):
    if user_films[str(x)][k]==0:
        return x
    else:
        pass
    


def recommend_for_user_k(k):
    recomend=[]
    for i in q_movies['movieId']:
            if user_films[str(i)][k-1]==0:
                recomend.append(q_movies.loc[q_movies['movieId']==i].index[0])
            if len(recomend) == 10:
                return recomend
    


recommend_for_user_k(1)

getAverageRatings(user_films, True)[0]

n=0
k=9
deleted=[]
for i in range (n,k):
    dict_={}
    p=10
    avg = getAverageRatings(user_films, True)[i]
    for j in movies_merged['movieId'].sample(frac = 1):
        if user_films[str(j)][i]>avg:
            dict_[(movies_merged[movies_merged['movieId']==j].index[0])]=user_films[str(j)][i]
            p=p-1
            user_films[str(j)][i]=0
        if p==0 :
            break
    deleted.append(dict_)

for user in (1,10):
    count=0 
    recs=recommend_for_user_k(user)
    for rec in recs:
        if users_films[str(dt_movies['movieId'][rec])][user]>0:
            count=count+1
    print(count/10)
        

dt_movies['movieId'][6298]

users_films[str(dt_movies['movieId'][6298])][1]

list(dict(sorted(deleted[2].items(), key=lambda item: item[1])).keys())

ndcg_score([[5,4,2,1]],[[5,0,0,0]])

[[0,0,3,0]]

recommend_for_user_k(1)

users_films

StarcoderdataJupyterScriptsDedupFiltered