def surprisetopN(algo, trainSet, raw_uid, N):
  """Derive the topN recommendations for user uid

  algo: scikit-surprise trained algorithm
  trainSet (surprise.dataset.Trainset)
  raw_uid (int or float): raw uid

  e.g. surprisetopN(algo, trainSet, 196, 3)

  Returns:
    list: (raw_iid, prediction) for the N recommended item_ids

  """
  inner_uid = trainSet.to_inner_uid(raw_uid)
  recom = []
  profile = set(map(lambda x: x[0], trainSet.ur[inner_uid]))
  for iid in trainSet.all_items():
    if iid not in profile: # item is unseen
      raw_iid = trainSet.to_raw_iid(iid)

      pred = algo.predict(raw_uid, raw_iid, r_ui=-1, verbose=False)
      recom.append((raw_iid, pred.est))

  recom = sorted(recom, key=lambda x: x[1], reverse=True)
  return recom[:N]