1

I have a text file that contains users username, password and highest score, however I want to overwrite their high score when the achieve a high score. However I only want to overwrite that specific value and no others.

This is my text file (called 'users.txt') :

david 1234abc 34 hannah 5678defg 12 conor 4d3c2b1a 21

For example, if 'hannah' gets a new score of 15, I want to change 12 to 15

Here is what I've tried:

# splitting the file
file = open("users.txt","r")
read = file.read()
users = read.split()
file.close()
# finding indexs for username, password and score
usernamePosition1 = users.index(user)
passwordPosition1 = usernamePosition1 + 1
scorePosition1 = passwordPosition1 + 1

file = open("users.txt","a")
# setting previous high score to an integer
player1OldScore = int(users[scorePosition1])


if player1Score > player1OldScore:
  # setting in back to a str for text file
  player1ScoreStr = str(player1Score)
  # from here on i dont really know what i was doing
  users.insert([scorePosition1],player1ScoreStr)
  file.write(users)
  print(player2 + "\n \nAchieved a new high score")
else:
  print("\n \n" + player1 + " , you didn't achieve a new high score")
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
codewizard
  • 11
  • 2
  • What you want to do is essentially random access to the file. But textfiles are not designed for that. You *can* do it but it is tricky and brittle. When processing a textfile the normal and easy approach is to read in the old version from one file and write out the new version to a fresh file. That of course means you have to manage deleting the old version and renaming the new version. The module `in_place` https://pypi.org/project/in-place/ will handle this for you elegantly. – BoarGules Jan 28 '19 at 21:26
  • Another option might be a simple `sqlite` database. – Mark Setchell Jan 28 '19 at 21:30
  • You could try to write it to a json file too. That would be an easier next step from textfile. – BugCatcherJoe Jan 28 '19 at 21:32
  • Does this answer your question? [How to modify a text file?](https://stackoverflow.com/questions/125703/how-to-modify-a-text-file) – mkrieger1 Jun 22 '20 at 13:06

3 Answers3

2

Your text file format is rather brittle. If David uses "hannah" as a password, then when Hannah tries to update her score, instead of locating her score (the sixth field), it will find her name as the second field and try using the fourth field (her name) as her score! Anyone using a space in their password would also cause problems, although a sneaky person could use “abcd 1000000” as their initial password and seed their initial score as one million.

These problems can be fixed by:

  • Using 1 line per user, or
  • Searching for user names only in the first of every 3 fields

And

  • disallowing spaces in passwords, or
  • coding/encrypting the passwords

In any case, you must read in and store the existing data, and then write out the entire dataset to the file. The reason is the data is not stored in fixed-width fields. A score changing from 99 to 100 will require moving all subsequent characters of the file one character forward, which is not a modification you can make to the file without actually reading and rewriting it in it’s entirety.

AJNeufeld
  • 8,526
  • 1
  • 25
  • 44
0

You are going to need to find and replace the strings. This means you will need to format the users.txt file in a way that you are able to simply replace the user data. If you have each user and their data on a seperate line this should be fairly easy:

import string
s = open("users.txt","r+")
for line in s.readlines():
   print line
   string.replace(line, 'hannah 5678defg 12','hannah gfed8765 21')
   print line
s.close()
Tom Dickson
  • 136
  • 9
0

You have the right idea (note that I your code will only work for 1 user, but I'll let you figure out how to extend it), but there is no way to change the file without writing the entire file.

As such I recommend something like this:

...
file = open("users.txt","w") # change this from 'a' to 'w' to overwrite
player1OldScore = int(users[scorePosition1])

if player1Score > player1OldScore:
  users[scorePosition1] = str(player1Score) # change the score
  file.write(" ".join(users)) # write a string with spaces between elements
  print(player2 + "\n \nAchieved a new high score")

...
nico
  • 2,022
  • 4
  • 23
  • 37