Anonymous
Anonymous

Reputation: 21

How to fix my leaderboard for my Music Quiz

I'm making a Music Quiz for a school project.

I've made a working game however I cannot get the leaderboard (which should be text and is saved as leaderboard.txt) to show different names as it overwrites the previous name.

For example, if "Sam" was to get a score of 9 and "Ben" was to get a score of 3, it would show up as "Ben-3-9" which is not what I'm after.

I am trying to get my leaderboard to work like:

Sam - 9
Ben - 3
...

My code looks like this right now:

username = input("What is your username?")
# this will ask for the persons name
password = str(input("What is the password?"))

# this will ask for a password which has been set already
if password == "1234":
    print("User Authenticated")

# if the password is incorrect, tell the user so and exit
elif password != "1234":
    print("Password Denied")
    exit()

# GAME
# Creating a score variable
score=0
x = 0
# Reading song names and artist from the file
read = open("songnames.txt", "r")
songs = read.readlines()
songlist = []

# Removing the 'new line' code
for i in range(len(songs)):
    songlist.append(songs[i].strip('\n'))

while x == 0:
    # Randomly choosing a song and artist from the list
    import random
    choice = random.choice(songlist)
    artist, song = choice.split('-')

    # Splitting the song into the first letters of each word
    songs = song.split()
    letters = [word[0] for word in songs]

    # Loop for guessing the answer
    for x in range(0, 2):
        print(artist, "".join(letters))
        guess = str(input("Guess the song!"))
        if guess == song:
            if x == 0:
                score = score + 3
                break
            if x == 1:
                score = score + 1
                break
            quit()

    # Printing score, Then waiting to start loop again.
    import time
    print("Your score is", score)
    print("Nice Work!")
    time.sleep(3)

leaderboard = open("leaderboard.txt", "r+")
leaderboard.write(username + '-' + '{}'.format(score))
leaderboard.close()
leaderboard = open("leaderboard.txt", "r+")
leaderboardlist = leaderboard.readlines()
print(leaderboardlist)
leaderboard.close()

PS: this is not 100% my code I am trying to get help from different places as my school has not taught us how to code yet due to the pandemic closing down schools.

Upvotes: 1

Views: 507

Answers (2)

Alex Mandelias
Alex Mandelias

Reputation: 517

The problem lies within the final few lines of code, where you are writing to the leaderboard.txt file.

Using "r+" indicates that you are updating (reading and writing) the file. Opening a file this way, moves the cursor at the beginning of the file. Therefore any attempt to write to the file will override whatever is already there.

The proper way to do it, is to open the file using "a" (or "a+" if you are planning to read as well). This is append mode and will move the cursor to the end of the file.

Some other general notes:

  • Use the with-as statement to handle closing the file automatically after you are done.
  • Use f-strings as opposed to string concatenation to increase readability

With that in mind, here's the code:

with open("leaderboards.txt", "a") as f:
    f.write(f"{username}-{score}")

For more on files, check this question.
For more on f-strings, check this quite extensive overview of them.

Upvotes: 3

tobias_k
tobias_k

Reputation: 82949

When you do this:

leaderboard = open("leaderboard.txt", "r+")
leaderboard.write(username + '-' + '{}'.format(score))

you open the leaderboard in read-and-write mode, but it will start writing at the beginning of the file, overwriting whatever is there. If you just want to add new scores to the leaderboard, the simplest would be to open the file in "append" mode "a":

with open("leaderboard.txt", "a") as leaderboard:
    leaderboard.write(username + '-' + '{}'.format(score))

Alternatively, you could open the file in "r" mode, then first read all the lines (scores) in a list or dictionary, merge / update them with the current player's new score (e.g. adding to the last score, replacing the last score, or getting the max of the new and last score of that player), and then open the file again in "w" mode and write the updated scores. (Left as an exercise to the reader.)

Upvotes: 4

Related Questions