[Tutor] high score lists

Chris Smith smichr at bigfoot.com
Fri Apr 15 06:07:19 CEST 2005

On Thursday, Apr 14, 2005, D. Hartley wrote:

> and  a question about sorting (either way):
>  I am trying it out with a list of tuples right now. The first problem
>  I ran into is that when i sort it (scorelist.sort(reverse=True)), it
>  sorts by the person's name (the first entry), and not by the score.

You aren't trying to do any fancy comparison; you just want to compare 
the 2nd values in a tuple rather than the tuple itself (in the case 
where the name comes first). So you supply a 2 argument function that 
returns the comparison of the 2nd values of two tuples:

def mycmp(a, b):
	return cmp(a[1], b[1])

And now do your sort like this:

high_scorelist.sort(cmp=mycmp, reverse=True)

On the other hand, if you put the numbers first then the task of 
printing is the problem..but that's easily overcome in your loop that 
prints the values: just print the number first!

for score, who in highscores:
	print score, who

which gives,
200 Nina
20 Ben
2 Raj

If you want to get the numbers looking pretty, try finding the longest 
number and then justify all numbers in a space that big:

highscores = [(200, 'Nina') , (20, 'Ben') , (2, 'Raj')]
longest_num = max( [ len(str(score)) for score,who in highscores] )
for score, who in highscores:
	print str(score).rjust(longest_num), who

which gives
200 Nina
  20 Ben
   2 Raj

>  plus I'm not quite sure yet how I'd get the user's name or score
>  *into* the list - without manually adding it as a tuple? Since I can't
>  do something like ... ("John", 100) .... username = "John", userscore
>  = 100, if userscore > lowestuserscore etc.

Your code was this:
def add_score(userscore):                                       #1
    if userscore[0] > high_scorelist[len(high_scorelist)-1][0]:  #2
        print "You made the high score list!"                    #3
        high_scorelist.append(userscore)                         #4
        high_scorelist.sort(reverse=True)                        #5
        del high_scorelist[len(high_scorelist)-1]                #6
        return high_scorelist                                    #7
    else:                                                        #8
        print high_scorelist                                     #9

Lines 2-7 handle the case when the user beats the high score but if 
they don't you go to line 9 and just print the high score without 
inserting them in the list to see if they make it. How about modifying 
this so the "else" part...
	appends the user to the list;
	sorts the list;
	keeps only the first 10 items;
	prints the list

List slices are a nice way to get the first 10 (or whatever) items of a 

 >>> def first10(l):
...  return l[:10]
 >>> print first10(range(20))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 >>> print first10(range(3))
[0, 1, 2]

One final note, in lines 2 and 6 you use "len(high_scorelist)-1" to get 
the last item of the list. A nice way to get the last item in the list 
is to use the index "-1" which refers to the "last one" in a list.  
(You can use negative indices, too.)

BTW, the HOWTO on sorting < 
http://www.amk.ca/python/howto/sorting/sorting.html > is helpful and 
the site starship site < 
http://starship.python.net/crew/theller/pyhelp.cgi > is a nice place to 
do a search of KEYWORDS (like sort) in python documentation.


More information about the Tutor mailing list