-1

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 save\n"))
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 for\n")

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")

dennobie
  • 1
  • 2
  • 2
    Welcome to StackOverflow, I'd suggest you remove `I'd also want the user to input the name of the contact that will be deleted when executed` as it makes the question less focused as it is separate from the original problem, which is not very much appreciated on StackOverflow. Please read https://stackoverflow.com/help/how-to-ask – Syed M. Sannan Nov 06 '22 at 16:45
  • You are asking for a new user to delete each time through the loop. You forgot the parentheses on `file.close()`. This exhibits no debugging effort. – tripleee Nov 07 '22 at 06:24

3 Answers3

0

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")
Booboo
  • 38,656
  • 3
  • 37
  • 60
0

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 123\nPeter Gabriel 456\n ...

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()
StehlikT
  • 13
  • 5
  • You are using the `find` method, which returns the lowest index of the sought string or -1. If the string you are looking for is at index 0, the `if` test will return `False` since 0 evaluates as `False`. Moreover, if it is not found at all, then -1 is returned and that evaluates as `True`. So you need `if line.find(user_input) != -1:`. Also, using `remove` as you are might require having to search the entire list find the element to remove. There are better ways. – Booboo Nov 06 '22 at 18:33
  • Thanks for clarifying, I'm always happy to learn. I wouldn't have posted my answer, had I seen yours before. But since I'm very new to SO, it took me quite some time to formulate it. Best – StehlikT Nov 06 '22 at 19:58
  • It's worth posting a second way of solving something. Yours is a different way (albeit it doesn't quite work as posted). To do it "your way", I would search `file_contents` by indexing elements of it from highest index (`len(file_contents) - 1`) to lowest (0) and if I find a "hit", I would call method `pop` passing the current index. By iterating from last to first, popping an element does not change the index of elements yet to be searched. – Booboo Nov 06 '22 at 20:07
0

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 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")
  • This is not effectively anything different from my answer. Also, `if not (delete == ""):` is more clearly expressed as `if delete != "":` – Booboo Nov 06 '22 at 18:36
  • @Booboo, and even more Pythonic: `if delete:` (although I would choose a more descriptive name as well) – wovano Nov 06 '22 at 20:16
  • Thank you for these tips I will make sure to keep them in mind next time. – Hugh Herschell Nov 07 '22 at 19:14