Binary file programs: search, append, update
Part of the free LogicWiz Python course, Pack A: CBSE Class 12 Board Pack. The examples and practice run in the app.
The 5-mark question in the board sample paper says: add employee records to a binary file, then update the salary of everyone in IT. Many students lose 3 of those 5 marks because they change the record in memory and never write it back to the file.
You'll learn to
- Search a binary file by roll number and say "not found" correctly
- Append new records with ab
- Update or delete records with read-modify-rewrite
Learn
The three board patterns
Almost every binary-file question is one of these:
- Search: read record by record; compare; set a
foundflag. - Append: open with
abanddump()the new record. - Update / delete: read all records into a list, change (or drop) the ones you want, then open with
wband dump them all back.
Why rewrite everything? Pickled records have different sizes ("Ananya" is longer than "Riya"), so you cannot safely overwrite one record in the middle of the file.
Search by roll number
import pickle
with open("stud.dat", "wb") as f:
for rec in ([101, "Aarav", 91], [102, "Meher", 78], [103, "Kabir", 85]):
pickle.dump(rec, f)
def search(roll):
found = False
with open("stud.dat", "rb") as f:
try:
while True:
rec = pickle.load(f)
if rec[0] == roll:
print("Name:", rec[1], "| Marks:", rec[2])
found = True
except EOFError:
pass
if not found:
print("Roll", roll, "not found")
search(102)
search(110)
Print "not found" after the loop, using a flag. If you put it in an else: next to the if, it prints once for every record that doesn't match: three "Not found" lines before the right answer.
Append records typed by the user
import pickle
def append_student():
roll = int(input("Roll: "))
name = input("Name: ")
marks = float(input("Marks: "))
with open("stud.dat", "ab") as f: # ab: add at the end
pickle.dump([roll, name, marks], f)
append_student()
append_student()
with open("stud.dat", "rb") as f:
try:
while True:
print(pickle.load(f))
except EOFError:
pass
ab also creates the file if it does not exist yet, so this works on a fresh folder.
Update: read all, change, rewrite
import pickle
with open("stud.dat", "wb") as f:
for rec in ([101, "Aarav", 91], [102, "Meher", 78], [103, "Kabir", 85]):
pickle.dump(rec, f)
def update_marks(roll, new_marks):
records = [] # step 1: read all
with open("stud.dat", "rb") as f:
try:
while True:
records.append(pickle.load(f))
except EOFError:
pass
changed = 0
for rec in records: # step 2: change in the list
if rec[0] == roll:
rec[2] = new_marks
changed += 1
with open("stud.dat", "wb") as f: # step 3: rewrite all
for rec in records:
pickle.dump(rec, f)
return changed
print("Updated:", update_marks(102, 88))
print("Updated:", update_marks(999, 50))
with open("stud.dat", "rb") as f:
pickle.load(f)
print(pickle.load(f))
Deleting is the same three steps, except in step 2 you keep only the records whose roll does not match.
The textbook rb+ way (seek and tell)
import pickle
with open("stud.dat", "wb") as f:
for rec in ([101, "Aarav", 91], [102, "Meher", 78], [103, "Kabir", 85]):
pickle.dump(rec, f)
f = open("stud.dat", "rb+")
try:
while True:
pos = f.tell() # where this record starts
rec = pickle.load(f)
if rec[0] == 102:
rec[2] = 95
f.seek(pos) # go back to its start
pickle.dump(rec, f) # overwrite it in place
break
except EOFError:
pass
f.close()
with open("stud.dat", "rb") as f:
print(pickle.load(f), pickle.load(f), pickle.load(f))
Many textbooks show this. It only works when the new record pickles to exactly the same size (78 → 95 does). Change a name to a longer one and the next record gets corrupted. The read-all-and-rewrite way is always safe.
Section E, 5 marks (2 + 3): (i) input a record and append it, (ii) update records that match a condition. Marks go to: import pickle, ab for append, the load() loop with EOFError, the condition, and writing the changed data back (wb + dump()). Use exactly the function names the question gives.
In one line
Search with a found flag; append with ab; update or delete by reading all records, changing the list, and rewriting with wb.