Day 048 - Project 48 : Saving a High Score Table

If you have any questions, comments or issues with this project please post them here!

Hi, Iā€™m struggling with Day48. The code isnā€™t failing but itā€™s also not adding to my file. Any help please?

while True:
name = input ("Input your initials: ")
score = input ("Enter your high score: ")
again = input (ā€œadd another? y/n? ā€œ)
if again == ā€œyā€:
continue
else:
break
f = open(ā€œHighScore.ā€, ā€œa+ā€)
f.write(fā€{name} {score}\nā€)
f.close()

As it stands youā€™re only writing the last entry to the files as you only get the the file writing code when the user breaks the loop and at that point the only name and score are the most recent.
Try

  name = input ("Input your initials: ")
  score = input ("Enter your high score: ")
  
  f = open("HighScore.", "a+")
  f.write(f"{name} {score}\n")
  f.close()

  again = input ("add another? y/n? ")
  if again == "y":
    continue
  else:
    break

And by moving the file writing code into the loop itā€™ll save after each one

2 Likes

Amazing - thank you!

Iā€™m back with another return question, and actual code!
I was working on this ā€˜create and edit an external fileā€™ problem. As I typed ā€œadd another?ā€ subroutine ā€œdef done()ā€, the AI popped in an "if yes, return true/if no return falseā€™ and I realized Iā€™ve never actually USED return true/return false. Iā€™ve only just read about it. So I incorporated it and am doing something wrong.
My code is a subroutine, ā€œdef done()ā€, and a while True loop.
In the subroutine, a Y returns True and an N returns False. So, I stuck an exit() command after, and NOT indented with, the while True loop. I thought that a returned False would end the while True loop and execute the exit() command.
I was mistaken. The returned False acts just like a returned True.
If I indent the exit(), as soon as the done() subroutine finishes, it exits. No surprise there.
I have completed the lesson without the return True/return False, so my question isnā€™t holding up my lesson.
Iā€™m posting the code (without comments) and my question is:
Did I format the code wrong or do I have a basic misunderstanding of the return True/False function and how it works?
Maybe both?
Thanks!
Drats

title = "šŸŒŸšŸŒŸšŸŒŸHIGH SCORE TABLEšŸŒŸšŸŒŸšŸŒŸ"
print(f"{title:^50}")


def done():
  fini = input("Add another?(Y/N)\n").title()
  if fini == "Y":
    return True
  elif fini == "N":
    return False
  else:
    print("Invalid Input, please try again.")
    done()


while True:
  f = open("scoreHIGH.txt", "a+")
  initials = input("Type your initials here: ")
  f.write(f"Initials: {initials}\n")
  score = input("Type your score here: ")
  f.write(f"Score: {score}\n\n")
  done()
exit()

no, for this you need if and break. Stuck? Think about function calls: wherever you write done() it is substituted for whatever value the function returns.

this bit can be simplified a bit. How? hint: when you return from a function, the function call cuts off and nothing further in the function will be evaluated, except finally statements. And think about how break worked to stop the code going back to the while True line.

6 Likes

Your placement of exit() outside the loop implies that regardless of what done() returns, the script will invariably execute the exit() function afterward. You should utilize the return value of done() within the loop to determine whether it continues or ends.

3 Likes

Sky,
This is where Iā€™m confused. I thought I WAS using the return value of done() to determine if the loop ends.
See, my thinking was:
ā€œas long as done() returns True, then the loop will continue. If done() returns False, the loop will stop and default to the next line, which is exit()ā€
My curiosity here is that since the AI suggested the return True/return False, there must be a way to use both return True and return False.
I guess the question now is ā€œis return True / return False a valid way to handle the done(), and if so, how?ā€

2 Likes

Here is the problem. Why would done() returning a value have any effect on the loop it was called inside? Python doesnā€™t go big brain mode and guess ā€œsince this person is calling a function to return a boolean, it must definitely be for the surrounding while loopā€, no.
You should use the return value of done(). (Also, what does this function return? Whether the user is done or whether the user wants to add another item?)

5 Likes

UMARismyname,
I appreciate the clear responses (and will be revisiting them a lot).
My question isnā€™t so much about how to end a loop. My question is more specifically how to use return True and return False in done() to affect the behavior of the while True loop.
Since the AI popped it in, I figured Iā€™d try it. My implementation didnā€™t work.
I hope that makes what Iā€™m trying to figure out a little clearer.

No, youā€™re not. Youā€™re simply calling done() without capturing the return value. Inside done(), use return done() instead. After finishing writing the score and initials, check the return value of done(). Exit the loop if done() returns False.

For done() instead of just calling done() do:

return done()

then inside of the while True loop you would do:

if not done():  
    break  

after you finish writing your data.

1 Like

NuclearPasta0
But thatā€™s the point: I thought I WAS using the return value of done() because the code said,

  if fini == "Y":
    return True
  elif fini == "N":
    return False

So I thought it was doing just that: returning True.
And thatā€™s the source of my question: how would I use that information in the while loop? Didnā€™t the ā€˜return Falseā€™ mean that while True is no longer active because done() returned False?

There are two different ways to use done() to affect the loop.
First, letā€™s address three important problems, and your question.

You are calling done() and expecting that the return statement inside of the function somehow affects the while loop. Why would it? Why should the function know anything about the loop at all? You are supposed to use the return value in any way youā€™d like.

What does done() return? It asks the user whether they want to add another item but the function name and return values donā€™t match. And when the user enters an invalid input, the function doesnā€™t really return anything at all (do you see a returned value in the else clause?)
Second, no need to call exit() at the end of the code if itā€™s the end of the program. Also, import sys and use sys.exit() rather than exit().
Third, you should properly manage your ā€˜resourcesā€™, the file you open. You never close the file, which can be a problem.

Here are two ways to structure the loop code:

with open("scoreHIGH.txt", "a+") as f:
  loop = True
  while loop:
    initials = input("Type your initials here: ")
    f.write(f"Initials: {initials}\n")
    score = input("Type your score here: ")
    f.write(f"Score: {score}\n\n")
    loop = not done()
with open("scoreHIGH.txt", "a+") as f:
  while True:
    initials = input("Type your initials here: ")
    f.write(f"Initials: {initials}\n")
    score = input("Type your score here: ")
    f.write(f"Score: {score}\n\n")
    if done():
      break  # breaks out of the loop
3 Likes

Isnā€™t that literally just what I said.

2 Likes

I am addressing other problems and the question. (The purpose and return value of the done() function is kind of ambiguous. Do you really want to break out of the loop when itā€™s ā€œnot done()ā€?)

3 Likes

Both approaches work, but honestly, using while not done() instead of while True seems better as it suggests the loop will continue as long as the user is not done entering scores, making it clearer in its intention to continue until the user decides to stop. :person_shrugging:

3 Likes

while not done() is not preferable because it needs to be a ā€˜do whileā€™ loop, the first time shouldnā€™t ask I assume.

3 Likes

NuclearPasta0,
Thanks for the added extra info, especially the resource management. I went back and checked my ā€˜finalā€™ code and itā€™s in there. Never would have really thought about it, though.

All,
OK, this is, for me, a TON of info to go through. Iā€™m going to play with it a bit more this evening and tomorrow. I imagine Iā€™m going to be spending a lot of time squinting at my screen and scratching my head!
I appreciate the time, effort, and thought in these replies (and am taking copious notes).
drats

2 Likes

while True would indefinitely iterate until a condition is met. Conversely, while not done() incorporates the exit condition within the while statement itself. Itā€™s a matter of preference, but @dratsaBgumS would need to place a while True loop inside the done() function instead if they plan on using while not done().

1 Like