hoe to delete specific strings in a python .txt file after accepting user input on what to delets

Question:

This is a python file that’s supposed to act like a phone book the file is called exam.txt its supposed to create, save, append, search and delete contacts but the delete part deletes all the strings instead of specific strings (the rest of the code is ok when executed the deleting part is the last part of the code)

#inputing contacts

filename ="exam.txt"
n = int(input("enter the number of contacts you would like to saven"))
file = open(filename, "a")

for i in range(n):
    cont = (input("enter name and phone number respectively:n"))
    file.write(cont + "n")

file.close

#searching for  contacts
word = input("insert the name you would like to search forn")

with open("exam.txt", "r") as file:
    for line_number, line in enumerate(file, start=1):
        if word in line:
          print(f"Word '{word}' found on line {line_number}")
          break
print("Search completed.")

#deleting contacts

# deleting a string/contact
try:
    with open('exam.txt', 'r') as fr:
        lines = fr.readlines()

        with open('exam.txt', 'w') as fw:
            for line in lines:

                # strip() is used to remove 'n'
                # present at the end of each line
                if line.strip('n') != input("input the contact you would like to delete:"):
                    fw.write(line)
                    break
    print("Deleted")
except:
    print("Oops! something error")

Asked By: dennobie

||

Answers:

A few improvements and corrections (for your specific issue, see Item 6).

  1. You are first asking the user to enter the number of contacts they wish to enter. What if they have a very long list? You are forcing them to have to manually count the number of names on the list. Better would be to continue entering until an empty line is entered. Nobody has to count anything.
  2. You have file.close. That just references a function without calling it. You need file.close(). Better yet is to use a context manager that will automatically issue the close for you (I see now you have already made this change).
  3. You have defined filename="exam.txt" That’s good (although using a variable name consisting of all capital letters is moreusual for defining constants). But later when you are in the contact-deletion code you hardcode "exam.txt" again. If you decide later to use a different file name you now have to change it in two places.
  4. In the contact-deletion code you are requesting the name of the contact for each line of the contact file. That cannot be what you really want, can it?
  5. In the deletion code you have the file opened twice concurrently, once for reading and once for writing. This is not required and is confusing.
  6. You need to write out every line in your lines variable, even after you found the contact to delete.
  7. Rather than use file.write(line + 'n'), you can do print(line, file=file) and the newline will be added automatically.
  8. A better choice of variable names makes the code clearer.
FILENAME = "exam.txt"

def get_contact():
    while True:
        contact = input("Enter the contact name: ").strip()
        if contact != '':
            return contact

#inputing contacts
print('Enter the name followed by a phone number for each contact you want to enter.')
print('When through, enter an empty line.')
print()
with open(FILENAME, "a") as file:
    while True:
        entry = input('Enter next name and phone numer: ').strip()
        if entry == '':
            break
        print(entry, file=file)

#searching for  contacts
contact = get_contact()

with open(FILENAME, "r") as file:
    for line_number, entry in enumerate(file, start=1):
        entry = entry.strip()
        if entry.startswith(contact):
            print(f"Contact '{contact}' found on line {line_number}: {entry}")
            # Uncomment out the following if you only want to list the first match:
            #break
print("Search completed.")

#deleting contacts

# deleting a string/contact
contact = get_contact()

try:
    with open(FILENAME, 'r') as file:
        entries = file.readlines()

    found_contact = False
    with open(FILENAME, 'w') as file:
        for entry in entries:
            # No need to strip off the 'n' at the end:
            if not entry.startswith(contact):
                print(entry, file=file, end='') # There is already a newline
                # or file.write(entry)
            else:
                found_contact = True

    if found_contact:
        print(f"Contact `{contact}` deleted.")
    else:
        print(f"Could not find contact '{contact}'.")
except:
    print("Oops! something error")
Answered By: Booboo

My knowledge about Python is pretty basic, but I think that the content of a file is overwritten as soon as you use the
open function in write "w" mode. My solution is to first read the lines into a list, delete the line specified by the user input and then use this list to re-write the file.
The format of my file is:

Michael Mueller 123nPeter Gabriel 456n

user_input = input("Please enter a name:")

file = open("pbook.txt")
file_contents = file.readlines()
file.close()

for index in range(int(len(file_contents) - 1), -1, -1):
    line = file_contents[index].strip()
    if line.find(user_input) != -1:
        print(f"{line} was removed from the phonebook.")
        file_contents.pop(index)

print(file_contents)
file = open("pbook.txt", "w")
file.writelines(file_contents)
file.close()
Answered By: StehlikT

try this for the delete function instead.

# deleting a string/contact
with open('exam.txt', 'r') as fr:
    # Get all the line/contacts from the file 
    lines = fr.readlines()
    # Get the string to be deleted.
    delete = input("insert the name you would like to delete: n")
    if not (delete == "" ):
        with open('exam.txt', 'w') as fw:
            for line in lines:
                # This will put back all lines that don't start with the 
                  provided string.
                if not (line.startswith(delete)):
                    fw.write(line)
        print("Deleted")
Answered By: Hugh Herschell