Day 049 - Project 49 : Loading a High Score Table

Hello All,
this my solution which is different to the solution as well :slight_smile:

python
list = []
maxscore = 0
maxname=""

f = open("high.score", "r")
print("")
print("HIGH SCORE TABLE")
print("")
for line in f:
  name, score_str = line.split()
  score = int(score_str)  
  list.append((name, score))
  if maxscore < score:
    maxscore = score
    maxname = name
  
f.close()

print(maxname, maxscore)
1 Like

Question: Declaring max = 0 and typecasting within ‘if’ statement renders ‘max’ as string. Whereas, separately typecasting variable ‘data’ renders ‘max’ as integer. Why this is happening? The solution given also typecasts within ‘if’ statement, but it throws no error.

Tutorial number: Day 49

Repl link: main.py - Day49_100Days - Replit

My code:

print("🌟Current Leader🌟\n\nAnalyzing high scores......\n")

max = 0
maxName = None

f = open("high.score", "r")
while True:
    contents = f.readline().strip()
    if contents == "":
       break
    uname, data = contents.split()
    # no error in following case:
    data = int(data)    
    if data > max:
        max = data
        maxName = uname

    # throws error if typecasted within 'if' statement:
    # [Error message: TypeError: '>' not supported between instances of 'int' and 'str']

    # if int(data) > max:
    #     max = data
    #     maxName = uname
    
f.close()

print(f"Current leader is {maxName} with score {max}")

Solution given:

import os, time

f = open("high.score", "r")
scores = f.read().split("\n")
f.close()

highscore = 0
name = None

for rows in scores:
  data = rows.split()
  if data != []:
    if int(data[1]) > highscore:
      highscore = int(data[1])
      name = data[0]

print("The winner is", name, "with", highscore)

This is because you later set max to a string.

max = 0
maxName = None

f = open("high.score", "r")
while True:
    contents = f.readline().strip()
    if contents == "":
       break
    uname, data = contents.split()
    # no error in following case:
    # data = int(data)    
    # if data > max:
    #     max = data
    #     maxName = uname

    # throws error if typecasted within 'if' statement:
    # [Error message: TypeError: '>' not supported between instances of 'int' and 'str']
    if int(data) > max:
        max = data  # <--- here, data is a string
        maxName = uname

Also, it is usually bad practice to “shadow”/overwrite builtin functions like max. What if you need to use that function later?

2 Likes

Thanks man for the clarification. I was scratching my head over this. I’m grateful for your kind help.

Anyone help me please? Also struggling with this. Literally don’t know what to do next. I’m in circles for more than three hours now…

f = open("high.score", "r")
print()
print("🌟Current Leader🌟")
print()
print("Analyzing high scores...")
print()
while True:

  contents = f.readline().strip()
  if contents == "":
    break

  contents = contents.split()

  element = int(contents[1])
  print(element)

  for index in range(len(contents)):
    print(f"{index}:{contents[index]}")


f.close()

It looks like all you need is to check which score/element is the highest.
I added the line highscore = 0 before your while True loop so we could have something to compare the scores to.

f = open("high.score", "r")
print()
print("🌟Current Leader🌟")
print()
print("Analyzing high scores...")
print()
highscore = 0 
while True:

  contents = f.readline().strip()
  if contents == "":
    break

  contents = contents.split()

  element = int(contents[1])
  if element > highscore:
    highscore = element
    winner = contents[0]

print(f"Highscore  is {highscore} held by {winner}")
  
f.close()

Then after you assign the score as element
we compare each score to the current high score,
if element > highscore:
if the score is higher than the current high score then, we assign the score as the new high score.
highscore = element
To get the name of the person with that score, we rely on the other part of the split from earlier.
winner = contents[0]

And finally we print the Highscore and the winner.
print(f"highscore is {highscore} held by {winner}")

It will say “winner is possibly unbound” because the variable winner is only assigned a value inside the if block within the while loop.

It will still work fine as is, but if you want to fix this you could just assign
winner = "noone"
before the while True loop starts

This makes it so that if no score was above 0, it would print “highscore is 0 held by noone” instead of causing NameError: name ‘winner’ is not defined.

f = open("high.score", "r")
print()
print("🌟Current Leader🌟")
print()
print("Analyzing high scores...")
print()
highscore = 0
winner = "noone"
while True:

  contents = f.readline().strip()
  if contents == "":
    break

  contents = contents.split()
  #print(f"{contents[0]} : {contents[1]}")

  element = int(contents[1])
  if element > highscore:
    highscore = element
    winner = contents[0]
    
print(f"High score is {highscore} held by {winner}")
  
f.close()

If you wanted to show all of the scores you can just uncomment the line
print(f"{contents[0]} : {contents[1]}")
under contents = contents.split()

We can imagine a scenario where 2 or more people have the same high score, and this code would only print one of their names.

If you wanted to control for this
f = open("high.score", "r")
print()
print("🌟Current Leader🌟")
print()
print("Analyzing high scores...")
print()
highscore = 0
winner = "noone"
while True:

  contents = f.readline().strip()
  if contents == "":
    break

  contents = contents.split()
  #print(f"{contents[0]} : {contents[1]}")

  element = int(contents[1])
  if element > highscore:
    highscore = element
    winner = contents[0]
  elif element == highscore:
    newwinner = contents[0]
    winner += f" and {newwinner}"

print(f"High score is {highscore} held by {winner}")


f.close()

Now if multiple people have the same score it will print all of their names instead of just one.

3 Likes

Thank you for your help. Looks like the hint by David about thinking of the index didn’t help me that much.

Your code is great but it still outputs the same winner multiple times instead of one (I also don’t know how to solve this)

Here’s the original highscore table I made for Day 48 which is also used for the current project

DMO 20332
K8T 398398398938
BRI 323232
SAM 494949

The code prints K8T and the highest score repetitively and also prints DMO 20332 despite the latter not being the winner. Do you know how to solve this?

You’re welcome and yes I see the problem and how to solve it.

You just need to unindent the line print(f"{winner} scores {highscore}")

How it’s indented now, it’s printing that line for each line in the high.score file

We only want it to print once, after it’s done checking every score, so we should unindent it.

3 Likes

Thank you so much! I’m surprised I didn’t figure that out. Still have a lot to learn…

When its indented, why does it print the DMO and its value first, then printed the highest score (K8T) three times but stop at printing BRI and SAM values?

Also sorry for some other silly questions (its from my lack of deep understanding of this I believe) but how does the computer selects the highest score if “if element > highscore: highscore = element:” when the element is now equal to every score in the row? Moreover, why does the element have to be compared to the high score and why must the high score = 0?

Apologies if I worded the questions poorly.

This is because it’s going through each score in the highscore file one by one, and after each one it prints whatever is the highest score so far. Since the highest score is the second score (K8T 398398398938) none of the scores after that will be higher, so it will remain as K8T 398398398938. It doesn’t print BRI and SAM because they’re after K8T but K8T’s score is still higher.

This is again because it’s going through each score one by one.
We start off with the high score as 0
It first checks if the first score in the file (DMO 20332) is greater than the current highscore (0)
since it is, it adjusts the highscore to that score.
It then checks if the next score in the file (K8T 398398398938) is greater than the current highscore (20332), since it is it adjusts the highscore again.
But since the remaining scores arent greater than 398398398938, when were done checking the scores we end with that as the highscore.

It doesn’t necessarily have to be that way, this is just one of many ways to do it.

We compare element to the highscore because that’s how we determine what the highest score is. element is the score for whichever line we are on in the highscore file and the highscore is the highest score out of the lines we’ve processed so far. It starts out at 0, because logically that’s what makes the most sense.
Imagine if you were playing a game that nobody could get a score greater than 50 points on, but in order for you to get your score on the leaderboards, you had to get atleast 1000 points, (though there are some games that work like this) we set the highscore at 0 to start with so that any score above 0 is enough to surpass it.

And your questions are great, I hope I could answer them adequately!

2 Likes

Thank you so much for your detailed explanations. Really appreciated it.

Can you also help me on this please?: Day 050 - Project 50 : Idea Storage System - #15 by MichaelDaburn

1 Like

Could you post that under the day 50 mega-thread?

They already did.

1 Like