Hi guys
I finally finished my highscore list but i have one problem I have to sort it.
I know how to sort regular list, but this is a bit different because of having the text in it. When I sort it I just get an weirdly sorted list. Does anyone one know how to properly sort it.
Here is my code:

## ~-~-~-~-~-~-~-~-~-~-~Pre MainLoop Declarations ~-~-~-~-
import csv
import string
import random
from HMGraphics import HangingMan

bKeepPlaying = True
## ~-~-~-~-~-~-~-~-~-~-~ Draws hangman to the screen base ~-~-~-~-
## ~-~-~-~-~-~-~-~-~-~-~ on how many error the play has ~-~-~-~-
def DrawErrors(iErrors):
    print HangingMan[iErrors]
       
## ~-~-~-~-~-~-~-~-~-~-~ Main Game Loop ~-~-~-~-
while bKeepPlaying == True:
## ~-~-~-~-~-~-~-~-~-~-~ Various Declarations ~-~-~-~-
    sWords= open("Dictionary.txt", "r")
    sHighScoreRead = open("HighScore.txt","r")
    sPrevHighScore = sHighScoreRead.readlines()
    sRawText = sWords.read()

    sWords=[]
    iStart=0
    iEnd=0
    iIndex =-1
    iWordNumber = 0
    iErrors = 0
    iScore = 0


    iGuesses = 0
    sLettersUsed = ""


## ~-~-~-~-~-~-~-~-~-~-~ Peel off words from list -~-~-
    for char in sRawText:
        iIndex += 1
        if(char == "~" and iIndex < 1):
            iEnd = iIndex
        if(char == "~" and iIndex > 1):
            iStart = iEnd
            iEnd = iIndex
            iWordNumber += 1
            sWords.insert(iWordNumber,sRawText[iStart+1:iEnd])
    


## ~-~-~-~-~-~-~-~-~-~-~ Create copy of random word -~-~-
## ~-~-~-~-~-~-~-~-~-~-~ and write it as a series of dashes-

    iRandomWord = int(random.random()*850)
    sAnswer = sWords[iRandomWord]
    sAnswer = list(sAnswer)
    sReveal = ""
    sReveal += len(sAnswer) * "-"
    sReveal = list(sReveal)

    print "".join(sAnswer)
    print "".join(sReveal)

## ~-~-~-~-~-~-~-~-~-~-~ Loop that get a letter from the player  ~-~-~-~-
## ~-~-~-~-~-~-~-~-~-~-~ and check if that letter exists in the correct word ~-~-~-~-
## ~-~-~-~-~-~-~-~-~-~-~ if it does it then replaces the dashes in the ~-~-~-~-
## ~-~-~-~-~-~-~-~-~-~-~ sReveal variable with the correct letter. ~-~-~-~-

    while True:

        sLetterGuess = str(raw_input("Please choose a letter "))
        
        if sAnswer.count(sLetterGuess) == 0:
            iErrors += 1
            sLettersUsed += sLetterGuess
            DrawErrors(iErrors)
            print sLettersUsed
        else:
            for i in range(len(sReveal)):
               if sAnswer[i]== sLetterGuess:
                   sReveal[i] = sLetterGuess
            print "".join(sReveal)
            sLettersUsed += sLetterGuess
            print "letters used : " + sLettersUsed
            
        if sReveal.count("-") == 0: #if there are no more dashes the player has guessed the right word
            print "You Won"
            iScore += (10 - iErrors)    #calculates the players score
            sPlayAgain = raw_input("would you like to play again (y/n)? ")
            if sPlayAgain == 'y':
                break
            else:
                bKeepPlaying = False
                sPlayerName = raw_input("Please enter your name for the highscore list: ")
                break
        elif iErrors >= 8:  #if they guess more then 8 letters wrong they lose.
            print "You Lost"
            sPlayAgain = raw_input("would you like to play again (y/n)? ")
            if sPlayAgain == 'y':
                break
            else:
                bKeepPlaying = False
                sPlayerName = raw_input("Please enter your name for the highscore list: ")
                break
            
## ~-~-~-~-~-~-~-~-~-~-~-put highscore information in notepad and display the highscores~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
sPrevHighScore += '\n' + sPlayerName + ", " + str(iScore)
sHighScoreWrite = open("HighScore.txt","w")
sHighScoreWrite.writelines(sPrevHighScore)
print "Your score was " + str(iScore)
print "These are the highscores"
print "".join(sPrevHighScore)
print "Thanks for playing!"


sHighScoreRead.close()#Closes the highscore list to clear the memory
sHighScoreWrite.close()
## ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-  

#                   PLAY AGAIN COMMENTS
## ~-~-~-~-~-~-~-~-~-~-~ Asks the player if they want to play again -~-~-
## ~-~-~-~-~-~-~-~-~-~-~ if they say no then it breaks out of loop -~-~-
## ~-~-~-~-~-~-~-~-~-~-~ and goes into main loop, but since the start condition -~-~-
## ~-~-~-~-~-~-~-~-~-~-~ (bKeepPlaying) will be equal to false, that loop will no longer run. -~-~-
## ~-~-~-~-~-~-~-~-~-~-~ if they say they do want to keep playing then the loop is -~-~-
## ~-~-~-~-~-~-~-~-~-~-~ broken out of, and we go back into the main game loop -~-~-
## ~-~-~-~-~-~-~-~-~-~-~ but since bKeepPlaying is equal to true it will still run. -~-~- 

#                   PLAY AGAIN CODE
##sPlayAgain = raw_input("would you like to play again (y/n)? ")
##if sPlayAgain == 'y':
##    break
##else:
##    bKeepPlaying = False
##    sPlayerName = raw_input("Please enter your name for the highscore list: ")
##    break

Also i would appreciate any other suggestions to make my code better.

Instead of:
"".join(sPrevHighScore)

maybe this:
"\n".join(sorted(sPrevHighScore.split("\n"),key=lambda x: int(x.split(",")[1].strip()), reverse=True))

In words:
You split sPrevHighScore into lines-
You split all lines based on coma.
You sort the lines based on the int value of the second tag
You sort reversed

Tested on: "\n".join(("lorem,20","ipsum,10"))

when i do this it give me an error:
Traceback (most recent call last):
File "C:\Users\Maryam\Desktop\Hangman\HangMan.py", line 117, in <module>
print "\n".join(sorted(sPrevHighScore.split("\n"),key=lambda x: int(x.split(",")[1].strip()), reverse=True))
AttributeError: 'list' object has no attribute 'split'

The first split is not neccesarry because you used readlines, which already gives back a list.
So
"\n".join(sorted(sPrevHighScore,key=lambda x: int(x.split(",")[1].strip()), reverse=True))

now I get this error.
Traceback (most recent call last):
File "C:\Users\Maryam\Desktop\Hangman\HangMan.py", line 145, in <module>
print "\n".join(sorted(sPrevHighScore,key=lambda x: int(x.split(",")[1].strip()), reverse=True))
File "C:\Users\Maryam\Desktop\Hangman\HangMan.py", line 145, in <lambda>
print "\n".join(sorted(sPrevHighScore,key=lambda x: int(x.split(",")[1].strip()), reverse=True))
IndexError: list index out of range

And btw thank you so much for all your time in helping me do this.

Okay i got a new sort highscore code all together. The problem is it wont sort, although It does seem to do it sometime.

def readHighScores():
    #opens guesshighscores.txt
    infile = open("HighScore.txt",'r')
    scores = [2,3,1]
    names = ["---","---","---"]
 
    #reads in scores from HighScore.txt
    for idx, line in enumerate(infile):
        scores[idx],names[idx] = tuple(line.strip().split())
    infile.close()
 
    return scores, names
 
 
def hasHighScore(score):
    #opens HighScore.txt
    scores, names = readHighScores()
 
    #compares player's score with those in HighScore.txt
    for elem in scores:
        if int(score) < int(elem):
            return True
    return False
 
def setHighScores(score, name):
    #opens HighScore.txt
    scores, names = readHighScores()
 
    # re-writes the list of highscores
    for idx, elem in enumerate(scores):
        if score > elem:
            continue
        scores.insert(idx, score)
        names.insert(idx, name)
        scores.pop()
        names.pop()
        break


    #writes new HighScore.txt
    outfile = open("HighScore.txt","w")
 
    i=0
    for i in range(0,len(scores)):
        outfile.write("\t" + str(scores[i]) + "\t\t\t" + names[i] + "\n")
    outfile.close()
    outfile = open('HighScore.txt', 'r')
    print outfile.read()
    outfile.close()

I would say it sort it in these line of code but I dont really understand it to well.

for idx, elem in enumerate(scores):
        if score > elem:
            continue
        scores.insert(idx, score)
        names.insert(idx, name)
        scores.pop()
        names.pop()
        break

For some reason its not working can anyone figure out why?

Do not expect anybody to solve the following problem:

I am thinking about a list
This list contains highscore and name pairs somehow
Please sort it somehow!

The reason i cannot use the built in sort is because there are the names in the list and since i want it to be sorted by the score i get a really weird outcome when i sort with the built in sort

What I want to do is somehow either seperate the name and score, or make a number be assigned a name so I can just write their score and the name will automaticlly come beside the score. I dont think the second one would work. Thats what I think that the code does, it seperates the text into a score and name, then sorts them according to score. BUT I dont fully understand this code and therefore I cant fix the bug that it doesn't sort properly.

If you need any more information just tell me.


Thanks for your time.

why dont you use a dict to save the name and scores? Then you can easy sort tham out.

why not make your algo. very simple for yourself?.

Let us suppose, we have a list:
hscore=["name1,100","name2,200","name3,100"]
If we do hscore.sort(), we get it sorted alphabetically.
That is why there is a "key" keyword to the sort method of the list.
The key accept a callable, that gives back the value if we apply it to each item.
So we need a function, that gives back the score if we give in the item.

input: "name1,100"
output: 100
this function can be: lambda x: int(x.split(",")[1])

test:
f=lambda x: int(x.split(",")[1])
f("name1,100")
# results 100

So hscore.sort(key=lambda x: int(x.split(",")[1])) will do the job.

The error:
The list does not consist of coma separated items. IndexError
Solution:
Correct list fill algo

The error:
The list item has coma, but the second item is not an int. TypError (?)
Solution
Correct list fill algo

This question has already been answered. Start a new discussion instead.