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.

Recommended Answers

All 11 Replies

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"))

It would be appreciated if you would read and tried to follow the naming rules of PEP8.

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?

Could you explain your algoritm and why you are not using the built in sort?

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

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.