1

Very short and simple. I am trying to create a highscore txt document for one of the games I'm making apart of a project. I want it to be able to keep the highest score ever reached in a text document so I can display it on the screen.

The file already exists, but whenever I load up the game, I get a "invalid literal for int() with base 10:" error. After looking, I realised this was because the file would delete anything inside of it when the program is started. Why is this? How can I fix it?

My code:

hisc = open("snakeScore.txt","w+")
highscore = hisc.read()
highscore_in_no = int(highscore)
if score>highscore_in_no:
            hisc.replace(str(score))
            highscore_in_no = score
duck2205
  • 11
  • 1

2 Answers2

1

Thats becuase You are using "w" when openning the file.

"w" Opens a file for writing. Creates a new file if it does not exist or truncates the file if it exists.

try using "r+" or "a"

  • this doesn't solve the issue, which would be opening the file with `a` to append –  Sep 16 '22 at 13:32
  • 1
    @SembeiNorimaki: The OP wants to read the contents and replace them. `a` alone won't allow the former, and it makes the latter more annoying than it really needs to be (now you need to seek to the beginning and truncate the file after reading, before writing, because `a` forces all writes to the end of the file). `r+` is the correct solution (`a+` can also be made to work, and will handle cases where the file doesn't already exist, though you might want to handle that case by catching the error when the file doesn't exist and creating it from scratch in that case). – ShadowRanger Sep 16 '22 at 19:02
0

From the documentation of Python3 for open:

  • r open for reading (default)
  • w open for writing, truncating the file first
  • '+' open for updating (reading and writing)

Then w+ will truncate the file before writing to it. You don't want that if you are required to read and store the content of it first.

Here's a working code, assuming that snakeScore.txt's content is a single line containing an integer, say "10":

score = 101
with open("snakeScore.txt", 'r+') as f:
    highestscore = int(f.read())
    if score > highestscore:
        f.seek(0)
        f.writelines(str(score))

The call to seek is needed in order to reset the pointer to the first line of the file, so we can rewrite the current line as opposed to adding a new one.

JustLearning
  • 1,435
  • 1
  • 1
  • 9
  • 1
    I do not like the summary of "In other words, writing is actually denoted by `+`", because this just means I'm going to end up reading more code where people who only need mode `"w"` add a `+` to it. `+` just means "I behave like the letter mode indicates, but can also do stuff from the other mode". That does mean anything with `+` can write (because the letter mode allows it, or the plus adds it), but it doesn't mean `+` is required to write (which is what your summary implies). – ShadowRanger Sep 16 '22 at 14:55
  • 1
    Also, there's no reason to call `writelines` for `f.writelines(str(score))`. It's a single `str`, so the behavior of `f.writelines` will be as if you called `write` for each character (the end result is the same, it's just a relatively roundabout way to do it). Just do `f.write(str(score))` and keep it to a single write operation. – ShadowRanger Sep 16 '22 at 14:56
  • I edited the explanation for `+` a bit, thanks for the input. For the second suggestion, OP doesn't provide details on the exact format of the input file, so I tried to keep things flexible by offering the chance to read lines. Let's have OP decide whether this is useful for their own application. – JustLearning Sep 16 '22 at 16:54
  • 1
    @JustLearning what does that have to do with your code using `writelines` in a way that is strange? `.writelines(str(c))` is always equivalent to `.write(str(c))` it is just a weird, unexpected way of doing it – juanpa.arrivillaga Sep 16 '22 at 18:48