code: def precision_recall_at_k(predictions, k=10, threshold=3.5):
      """Return precision and recall at k metrics for each user"""
  
      # First map the predictions to each user.
      user_est_true = defaultdict(list)
      for uid, _, true_r, est, _ in predictions:
          user_est_true[uid].append((est, true_r))
  
      precisions = dict()
      recalls = dict()
      for uid, user_ratings in user_est_true.items():
          # Sort user ratings by estimated value
          user_ratings.sort(key=lambda x: x[0], reverse=True)
  
          # Number of relevant items
          n_rel = sum(
              (true_r >= threshold) for (_, true_r) in user_ratings
          )
  
          # Number of recommended items in top k
          n_rec_k = sum(
              (est >= threshold) for (est, _) in user_ratings[:k]
          )
  
          # Number of relevant and recommended items in top k
          n_rel_and_rec_k = sum(
              ((true_r >= threshold) and (est >= threshold))
              for (est, true_r) in user_ratings[:k]
          )
  
          # Precision@K: Proportion of recommended items that are relevant
          # When n_rec_k is 0, Precision is undefined. We here set it to 0.
  
          precisions[uid] = (
              n_rel_and_rec_k / n_rec_k if n_rec_k != 0 else 0
          )
  
          # Recall@K: Proportion of relevant items that are recommended
          # When n_rel is 0, Recall is undefined. We here set it to 0.
  
          recalls[uid] = n_rel_and_rec_k / n_rel if n_rel != 0 else 0
  
      return precisions, recalls
  
imports: from collections import defaultdict
  from surprise import Dataset, SVD
  from surprise.model_selection import KFold
label_desc: Use image node_id 1 for calling a global function with example usage: precision_recall_at_k(predictions, k, threshold) and returns: precisions,  recalls