Python Forum
Highscore problem, need to print top 5
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Highscore problem, need to print top 5
#1
I need for it to print the top 5 scores, but at the moment it is only printing the highest scores that have ever been the top scores, if that makes sense. Any help would be much appreciated. Here is the whole code, and then the external files that are relevant. Python version is 3.4.1. I couldn't find out how to do it online and my teacher won't help me. I just can't think of a way to fix it.

Context: Basically I have to make a music game where you need to log in to the game, and then you would be given a music artist and the first letter of each word in one of their songs, this bit is random. Then the user would input their guess of what the song is, if guessed correctly on their first go then they would earn 3 points, on their second go, 1 point and third go, you lose the game. The user has to try and get as many points as possible. There is a high score system which is all recorded in an external file. The game will output the top 5 highscores. My problem is getting it print the top 5 scores rather than the latest top score. Thanks.

import random

def readData():
    with open("Song Names.txt", "r") as f:
        songNames = [line.rstrip('\n') for line in f]
        f.close()
    with open("Artist Names.txt", "r") as f:
        artistNames = [line.rstrip('\n') for line in f]
        f.close()
    with open("Usernames.txt", "r") as f:
        usernames = [line.rstrip('\n') for line in f]
        f.close()
    with open("Passwords.txt", "r") as f:
        passwords = [line.rstrip('\n') for line in f]
        f.close()
    return songNames, artistNames, usernames, passwords

def login(usernames, passwords):
    existing = input("Are you an existing user?")
    if existing == 'no' or existing == 'n' or existing == 'NO' or existing =='No' or existing == 'nO':
        newname = input("Enter new username: ")
        newpass = input("Enter new password: ")
        createu = open("Usernames.txt", "a")
        createu.write("\n"+ newname)
        createu.close()
        createp = open("Passwords.txt", "a")
        createp.write("\n"+ newpass)
        createp.close()
        print("Restart game to login")
    elif existing == 'yes' or existing == 'y' or existing == 'YES' or existing == 'Yes' or existing == 'yEs' or existing == 'yeS':
        global enterUsername
        enterUsername = input("Enter username\n> ")
        if enterUsername in usernames: 
            enterPassword = str(input("Enter password\n> ")) 
            usernamePos = usernames.index(enterUsername) 
            if enterPassword in passwords: 
                passwordPos = passwords.index(enterPassword) 
                if usernamePos == passwordPos: 
                    print ("You are logged in", enterUsername) 
                    return True
                else: 
                    print("You entered the wrong password...") 
            else: 
                print("That password is not in the file...")
        else: 
            print("You're not allowed to play the game...") 
        return False 
    else:
        print("What?")
def chooseSong(songNames, artistNames): 
    unknownSong = random.choice(songNames) 
    sSP = songNames.index(unknownSong) 
    unknownArtist = artistNames[sSP] 
    return unknownSong, unknownArtist 
        
def preGame(unknownSong, unknownArtist): 
    word_guessed = []
    songs = unknownSong.split()
    letters = [word[0] for word in songs]
    print ("The artist is ", unknownArtist, "and the song is", "".join(letters))
    for letter in unknownSong: 
        if letter == " ": 
            word_guessed.append(" / ")        
        else: 
            word_guessed.append("-") 
    for letter in word_guessed: 
        print (letter, end = " ")
    return unknownSong

def playGame(unknownSong, score): 
    tries = 0 
    while True:
        userGuess = str(input("\nWhat is the song name?\n> "))
        if userGuess == unknownSong: 
            print("Correct!") 
            if tries == 0:
                score = score + 3 
                print("You earnt 3 points! You have", score, "points in total.")  
                return score, True 
            elif tries == 1: 
                score = score + 1 
                print("You earnt 1 point! You have", score, "points in total.")  
                return score, True 
        else:
            tries = tries + 1 
            if tries == 2: 
                print ("Game over! You got", score, "points!")
                return score, False 
                break 
                print("You have 1 try left.") 
            else:
                print("Incorrect!")
                print("You have 1 try left.")

def highScore(score, enterUsername):
    highscore = 0
    last_high_score = 0
    text_file = open("Scores.txt", "r")
    for line in text_file.readlines():
        line_parts = line.split(" has a score of ")
        if len(line_parts) > 1:
            line_parts = line_parts[-1].split("\n")
            highscore = line_parts[0]
            if int(highscore) > last_high_score:
                last_high_score = int(highscore)
    if int(score) > last_high_score:
        text_file = open("Scores.txt", "a")
        text_file.write("\n"+ str(enterUsername) +' has a score of '+ str(score) +"\n")
        text_file.close()

    print ("\n")
    text_file = open("Scores.txt", "r")
    whole_thing = text_file.read()
    print (whole_thing)
    text_file.close()

def main():
    songNames, artistNames, usernames, passwords = readData()
    score = 0
    success = login(usernames, passwords)
    if success == True: 
        while True: 
            print ("Rules: Song must be in full capitals, don't put a space after your answer")
            unknownSong, artist = chooseSong(songNames, artistNames)
            preGame(unknownSong, artist)
            score, win = playGame(unknownSong, score)
            if win == False:
                highScore(score, enterUsername)
                break
main()
Usernames:
• John
Greg
Secure
INeed
MyHighscore
Thank

Passwords:
• Smith
Heffley
Password
Help
IsntWorking
You
Scores:


Scores external file is currently empty but it would have the top score for each user inside.
Thank you very much.
Reply
#2
Well the problem is, that you tell the program to print all high scores that were ever made.
instead of doing this:
text_file = open("Scores.txt", "r")
whole_thing = text_file.read()
print (whole_thing)
text_file.close()
you could simply do this
with open("Scores.txt", "r") as text_file:
    lines = text_file.readlines()
    top_5_scores = reverse([f.rstrip() for f in lines][-5 if len(lines > 4) else 0:])
The good thing is, you already sort the file while building it. Since you check if the new score is higher than the highest high score and then append it to the end, the scores are sorted from lowest to highest.
so you could reduce the highscore function to this:
def highScore(score, enterUsername):
    highscore = 0
    last_high_score = 0
    with open("Scores.txt", "r") as text_file:
        line_parts = text_file.readlines()[-1].split(" has a score of ")
        if len(line_parts) > 1:
            last_high_score = int(line_parts[0])
    if int(score) > last_high_score:
        with open("Scores.txt", "a") as text_file:
            text_file.write("\n"+ str(enterUsername) +' has a score of '+ str(score) +"\n")
 
    print ("\n")
    with open("Scores.txt", "r") as text_file:
        top_5_scores = reverse([f.rstrip() for f in text_file.readlines()][-5 if len(lines > 4) else 0:]
        for entry in top_5_scores:
             print(entry)
Reply
#3
(Jan-28-2020, 01:14 PM)ThiefOfTime Wrote: Well the problem is, that you tell the program to print all high scores that were ever made.
instead of doing this:
text_file = open("Scores.txt", "r")
whole_thing = text_file.read()
print (whole_thing)
text_file.close()
you could simply do this
with open("Scores.txt", "r") as text_file:
    lines = text_file.readlines()
    top_5_scores = reverse([f.rstrip() for f in lines][-5 if len(lines > 4) else 0:])
The good thing is, you already sort the file while building it. Since you check if the new score is higher than the highest high score and then append it to the end, the scores are sorted from lowest to highest.
so you could reduce the highscore function to this:
def highScore(score, enterUsername):
    highscore = 0
    last_high_score = 0
    with open("Scores.txt", "r") as text_file:
        line_parts = text_file.readlines()[-1].split(" has a score of ")
        if len(line_parts) > 1:
            last_high_score = int(line_parts[0])
    if int(score) > last_high_score:
        with open("Scores.txt", "a") as text_file:
            text_file.write("\n"+ str(enterUsername) +' has a score of '+ str(score) +"\n")
 
    print ("\n")
    with open("Scores.txt", "r") as text_file:
        top_5_scores = reverse([f.rstrip() for f in text_file.readlines()][-5 if len(lines > 4) else 0:]
        for entry in top_5_scores:
             print(entry)

I really appreciate your help and your quick reply but unfortunately, I now get this error:

Error:
line 101, in highScore last_high_score = int(line_parts[0]) ValueError: invalid literal for int() with base 10: 'Thank'
The score file is now:


Thank has a score of 15
Reply
#4
I am sorry, my bad :) i parsed the name of the player in there, not the score. just change it to:
if len(line_parts) > 2:
    last_high_score = int(line_parts[-1])
Reply
#5
(Jan-29-2020, 01:10 PM)ThiefOfTime Wrote: I am sorry, my bad :) i parsed the name of the player in there, not the score. just change it to:
if len(line_parts) > 2:
    last_high_score = int(line_parts[-1])

Thank you very much, sorry if I'm getting a bit annoying but I now get this error

Error:
line 108, in highScore top_5_scores = [f.rstrip() for f in text_file.readlines()][-5 if len(lines > 4) else 0:] NameError: name 'lines' is not defined
Reply
#6
You are not annoying me, don't worry. Again, it is my fault, I modified the code locally and somehow forgot this line. lines is not defined of course, the last part was ment like that:
with open("Scores.txt", "r") as text_file:
    lines = text_file.readlines()
    top_5_scores = reverse([f.rstrip() for f in lines][-5 if len(lines > 4) else 0:]
    for entry in top_5_scores:
         print(entry)
I am really sorry. This should work now.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  problem with print command in super() akbarza 5 507 Feb-01-2024, 12:25 PM
Last Post: deanhystad
  problem with spliting line in print akbarza 3 336 Jan-23-2024, 04:11 PM
Last Post: deanhystad
  problem with print lists MarekGwozdz 4 613 Dec-15-2023, 09:13 AM
Last Post: Pedroski55
  Problem with print variable in print.cell (fpdf) muconi 0 633 Dec-25-2022, 02:24 PM
Last Post: muconi
  C to Python code conversion print problem anakk1n 1 2,138 May-22-2020, 04:15 PM
Last Post: deanhystad
  problem with print format anna 7 4,260 May-16-2018, 11:28 AM
Last Post: anna

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020