0

So right now I have a text file which is formatted like this:

ID1 - Reason for ban
ID2 - Reason for ban
ID3 - Reason for ban

I have a command that basically removes the user's ban and that should delete the users details in the text file.

ID2 = 12345 #sample ID
with open("yourfile.txt", "r") as f:
  lines = f.readlines()
with open("yourfile.txt", "w") as f:
  for line in lines:
    ID, reason = line.split(" - ")
    if ID == ID2:
      f.write("\n")    
          

The code above deletes everything regardless of if the ID matches or not, is there another solution that could detect if the ID in the textfile matches up with the users request?

SpaceTurtle0
  • 163
  • 3
  • 18
  • 2
    Does this answer your question? [How to delete a specific line in a file?](https://stackoverflow.com/questions/4710067/how-to-delete-a-specific-line-in-a-file). Basically, reverse the condition. Write it back *only* if it's not the matching ID. – Gino Mempin Nov 29 '20 at 23:39
  • 2
    `split` of a string returns strings, and the returned result will never compare equal to the integer `ID2`. – Peter S. Housel Nov 29 '20 at 23:42

3 Answers3

3

In addition to an else: block, to be able to compare the IDs, you need your ID2 to be a string, or you need to convert the ID you're extracting from the file into an int.

Here is a version with a string:

ID2 = '12345' #sample ID

with open("test.txt", "r") as f:
    lines = f.readlines()

with open("yourfile.txt", "w") as f:
    for line in lines:
        ID, *rest = line.strip().split()

        if ID == ID2:
            f.write("\n")
        else:
            f.write(line)

You can skip the if-else, and simply write a line of text if IDs are not equal in a single if statement, unless you want a newline break - i.e. an empty line instead.

Regarding line splitting, I personally always use strip() to get rid of any leading and trailing whitespace. Additionally, splitting by whitespace has its benefits, you don't need to think if there was an accidental tab between ID and -. So here, you split it and extract the ID, and the "rest", literally labelled as *rest - since you don't need it anyway.

atru
  • 4,699
  • 2
  • 18
  • 19
2

You are not rewriting the original file. Just adding one enpty line.

Use this to add the rest:

ID2 = 12345  # sample ID
with open("yourfile.txt", "r") as f:
    lines = f.readlines()

with open("yourfile.txt", "w") as f:
    for line in lines:
        ID, reason = line.split(" - ")
        if ID == ID2:
            f.write("\n")
        else:
            f.write(line)

Or use:

if ID != ID2:
    f.write(line)

If you do not want to create an empty line where the old one was.

Arthur Pereira
  • 1,509
  • 2
  • 8
  • 18
1

Your code doesn't write the good lines that you want to keep. Only a single "\n" in the case where ID matches. But ID will never match because you are comparing an integer to a string, so its always empty. Since your plan is to write an empty line in place of the unbannded ID, future runs will fail when you try to ID, reason = line.split(" - ").

Instead, you could build a string to match at the front of the line and avoid the exception. Its a good idea to write to a temporary file first than to risk the entire file being deleted because of a programming bug.

import os

ID2 = 12345 #sample ID
unban_id = f"{ID2} - "

with open("yourfile.txt", "r") as f:
    lines = r.readlines()
with open("yourfile.txt.tmp", "w") as out:i
    f.writelines(line if line.startswith(unban_id) else "\n" for line in lines)
os.rename("yourfile.txt.tmp", "yourfile.txt")
tdelaney
  • 73,364
  • 6
  • 83
  • 116