On 9/20/05, Jason <[EMAIL PROTECTED]> wrote: > class HiScores: > def __init__(self,hiScores): > self.hiScores=[(entry[:5],entry[5:]) for entry in hiScores]
In your original code, you were using slicing to extract the first five digits (being the score) from the string; now that you're using tuples of (score, name), you don't need the slicing at all. In fact, the slicing here is not doing what you expect. If we consider a single instant in this list comprehension, then this is doing the equivalent of: entry = ('10000','Alpha') a = entry[:5] # ('10000', 'Alpha'), as entry only has two items b = entry[5:] # (), as entry has only two items new_entry = (a, b) So the entry in self.hiScores corresponding to this would be a tuple (('10000', 'Alpha'), ()). When (in showScores()) you use this with % name, score -- name is the first tuple ('10000', 'Alpha'), and score is the second (). The % operator takes (always!) a single tuple, and finds the '10000' and 'Alpha' to match the two "%s"; then score is just printed afterwards, which is just () here. Since all you want to do here in __init__() is copy the input, you could use the following: self.hiScores=[(entry[0],entry[1]) for entry in hiScores] Or, using Python's tuple-unpacking, you can get a clearer version: self.hiScores=[(score, name) for score, name in hiScores] But since tuples are immutable, it is generally safe to grab another reference to a tuple instead of copying it; so we can just copy the whole list: def __init__(self,hiScores): self.hiScores=list(hiScores) I'd also recommend that you use ints, not strings, to store the scores; when printing the scores, you can use the formatting options of %d to display the score with the appropriate number of zeroes; or you could use str(score).zfill(5) if it makes more sense to you (I haven't given you an example of this change). % substitution has its own trap, in that the , operator has lower precedence than %, so whenever you want to use more than one value with %, you need to wrap them all in parentheses: def showScores(self): for name,score in self.hiScores: print "%s - %s" % (name,score) > def addScore(self,score,name): > score.zfill(5) > bisect.insort(self.hiScores,(score,name)) > if len(self.hiScores)==6: > self.hiScores.pop() If you use ints to store your score, you can remove the line calling .zfill() here. You'll need to import the bisect module before you can use it. Note that bisect.insort() will not work as expected if the list is not in sorted order. You should make sure the list is sorted in __init__. > def main(): > > hiScores=[('10000','Alpha'),('07500','Beta'),('05000','Gamma'),('02500','Delta'),('00000','Epsilon')] > > a=HiScores(hiScores) > print "Original Scores\n---------------" > a.showScores() > > while 1: > newScore=random.randint(0,10000) > if newScore.zfill(5) > a.lastScore(): > I've read as many websites as I can about zfill and I can't see why on > earth it's failing. random.randint() returns an int; zfill() is a method of strings. If you use ints for the score (as recommended above), then you need only compare newScore > a.lastScore(); if you want to continue using strings, then you'll need to use str(newScore) to get a string. > 2) The output of the predefined hiscores is now... > > Why are there the pairing parenthesis there? George very kindly showed > me another way which was to have... I've tried to explain why this is occurring above -- it's due to a bug in __init__(), and another in showScores(). > def showScores(self): > for entry in self.hiScores: > print entry[0:5]," - ",entry[5:] > > But using that method output the entire list in it's full format (sorry > if that's not the correct terminology). But give me a small plus mark > for changing code and not simply copying George :) No, you made almost exactly the right change to showScores() needed because of using tuples to store the name and score. You only tripped over the % name, score instead of % (name, score) problem that almost everyone makes (I still do it regularly). > > 3) The hardest thing to 'understand' is the line... > self.hiScores=[(entry[:5],entry[5:]) for entry in hiScores] > > I 'understand' what it's doing, but I don't quite comprehend what the :5 > and 5: do. I know that the :5 is technically saying from the start to > position 5, and likewise the 5: would say from position 5 onwards, but I > just can't get my head around how this works. See my explanation of __init__(). Does that help? Andrew -- http://mail.python.org/mailman/listinfo/python-list