0

I am storing the records in form of a list.

Write a menu driven program to append, display and delete student details [id, name, percentage] in a binary file. Deletion should be done on the basis of student id.

So I wrote this:

#Code to append display and delete student details
import pickle
def append():
    f = open("student.bin","ab")
    x = int(input("Enter number of students to be appended: "))
    for i in range(x):
        y = eval(input("Enter details in the form [id, name, percentage]: "))
        pickle.dump(y,f)
    f.close()

def display():
    f = open("student.bin","rb")
    while True:
        try:
            x = pickle.load(f)
            print(x)
        except EOFError:
            break
    f.close()

def delete():
    f = open("student.bin","ab+")
    x = input("Enter id to be deleted: ")
    y = pickle.load(f)
    for i in y:
        if str(i[0]) == str(x):

In the end, I was matching the user input to the matching IDs but I don't know how I should go about deleting the list entirely from the binary file.

martineau
  • 119,623
  • 25
  • 170
  • 301
  • 1
    Pickle files weren't designed to be incrementally updated, so you will need to rewrite the whole thing whenever you have changes you want to make. I would suggest storing the data for the students in a container like a list or dictionary and the loading the whole thing into memory, updating it (e.g. add, change, or delete the some of the data in it), and then dumping the updated version back out. You may find my [answer](https://stackoverflow.com/a/4529901/355230) to related question helpful. – martineau Sep 04 '21 at 17:25

1 Answers1

0

Here is one way: reads all the student records from file, remove the one we want to delete, then write the whole list back into file.

def delete():
    student_id = int(input("Enter id to be deleted: "))
    records = []
    with open("student.bin", "rb") as stream:
        while True:
            try:
                record = pickle.load(stream)
                if record[0] != student_id:
                    records.append(record)
            except EOFError:
                break
    
    # records now contains all students, except for the one we want to delete
    with open("student.bin", "wb") as stream:
        for record in records:
            pickle.dump(record, stream)

Another way is to open the file for read/write and load each record and write it back. It is harder to understand.

Hai Vu
  • 37,849
  • 11
  • 66
  • 93
  • Would only require one `pickle.load()` and `pickle.dump()` call if the students where all stored in a list and it was the only object in the file. – martineau Sep 05 '21 at 18:07