Q:

Correct implementation of determining position in the list

I have a list of favourite movies and I'd like to sort them according to my taste from the best movies (have most points) to worst movie (has only 1 point).
Lets say the list contains already 300 sorted movies and you want to determine points for the new movie. You could compare the new movie with every movie in the sorted list or you can utilize the knowledge that the list is sorted.
I tried to implement it as a binary search so every insert (of new movie) has logarithmic complexity.
The binary search implementation was easy for me:
def binSearch(lst, number):
  left = 0
  right = len(lst) - 1
  while left <= right:
    middle = left + ((right - left) / 2)
    if number == lst[middle]:
      return True
    else:
      if number < lst[middle]:
        right = middle - 1
      else:
        left = middle + 1
  return False

But determining points is quite difficult for me. I'm already debugging it for a few hours and still some errors occur. I changed the implementation many times but nothing helps.
Here is my last solution (maybe the algorithm is in the worse state then it was at the beginning)
def determinePoints(lst, new):
  # lst is a list of tuples with movies
  # new is a tuple with new movie (has no point associated yet)
  if not lst: # no movie has points so far
    return 1 #  now exists only one movie with associated points
  newTitle = new[0]
  newGenre = new[1]
  atMost = len(lst)
  atLeast = 0
  while atLeast < atMost - 1: # algorithm doesn't work
                              # if only two movies have associated points
    center = twoPointsCenter(atLeast, atMost)
    (title, genre) = lst[center]
    os.system("clear")
    competitionStrings = [ newTitle, newGenre, "\n" * 10, title, genre ]
    print "\n".join([ x.center(150) for x in competitionStrings ])
    c = getch()
    if c == "j": # new movie is worse than this
      atMost =  center - 1
      if atMost <= 1:
        return 1
    else: # new movie is better than this
      atLeast = center + 1
      if atLeast >= len(lst):
        return max(atLeast, 1)
  return max(twoPointsCenter(atLeast, atMost), 1)

def twoPointsCenter(left, right):
  return left + ((right - left) / 2)

Could you correct my solution (or implement it better) to converge and end with the right result?
It should work with lst of lengths from 0, 1, 2, ... etc. It shouldn't return value less than 1. In the list of movies there shouldn't be two movies with the same number of points.
When the function determinePoints returns points, I will update the database for this movie and increment points by 1 for each movie with >= points than this new movie.
Thank you

A:

I think you need to better look at the boundary indexes. len(lst) is one larger than the maximal index, for example: lists are 0-based. I took the liberty to use 0 as lowest possible score; this will directly give you the position to lst.insert at. Also, I couldn't resist and made this a little more PEP 8-like.
You don't need all the corner cases; they just work fine, I think.
def determine_points(lst, new):
  # lst is a list of tuples with movies, ranked by how good the movie is
  # new is a tuple with new movie
  # the new movies position is to be determined

  new_title, new_genre = new
  at_most = len(lst)
  at_least = 0
  while at_least < at_most:
    center = (at_least + at_most) // 2
    title, genre = lst[center]
    os.system("clear")
    competition_strings = [new_title, new_genre, "\n" * 10, title, genre]
    print("\n".join(x.center(150) for x in competition_strings))
    c = getch()
    if c == "j": # new movie is worse than this
      at_most = center
    else: # new movie is better than this
      at_least = center + 1
  return at_least

Edit: I tested with the following code.
lst = []
news = [(str(i), str(i)) for i in range(10)]
import random
random.shuffle(news)
for new in news:
    print(lst)
    lst.insert(determine_points(lst, new), new)
print(lst)

