I have built a sample Parser class on top of the csv module for basic checks that we normally need as the first step of pre-processing. I would love a bit of feedback on the code and any areas that I can improve upon in the code to make it more efficient.
import csv
from exceptions import CompulsoryHeaderCheckFailed
class CsvParser:
def __init__(self, file: str, compulsory_headers: list):
self.file = file
self.compulsory_headers = compulsory_headers
self.duplicate_rows = []
self.good_rows = []
self.bad_rows = []
self.log = []
def diff_headers(self):
reader = csv.reader(open(self.file))
header = next(reader)
return set(self.compulsory_headers) - set(header)
def passes_compulsory_header_check(self):
return True if not self.diff_headers() else False
def is_bad_row(self, line_num: int, curr_row: tuple):
if not all(curr_row):
self.bad_rows.append(({"line_num": line_num, "row": list(curr_row)}))
return True
return False
def _append_log(self, line_num: int):
self.log.append({"total_num_of_rows_processed": line_num,
"good_rows": self.good_rows,
"bad_rows": self.bad_rows,
"duplicate_rows": self.duplicate_rows,
})
@property
def row(self):
rows = csv.reader(open(self.file))
next(rows)
for _row in rows:
yield _row
@property
def col(self):
rows = csv.reader(open(self.file))
for row in rows:
return row
def _parse_rows(self):
_rows = set()
rows = csv.reader(open(self.file))
next(rows)
line_num = 1
_rows = set()
for row in rows:
line_num += 1
row = tuple(row)
if not (self.is_bad_row(line_num, row)):
if row not in _rows:
_rows.add(row)
self.good_rows.append({"line_num": line_num, "row": list(row)})
else:
self.duplicate_rows.append({"line_num": line_num,
"row": list(row)
})
self._append_log(line_num)
def process_csv(self, skip_header_check=False):
if skip_header_check:
self._parse_rows()
else:
if self.passes_compulsory_header_check():
self._parse_rows()
else:
raise CompulsoryHeaderCheckFailed("compulsory headers missing from csv")
csv_parser = CsvParser("hello.csv", compulsory_headers=["id", "student", "marks", ])
print(csv_parser.process_csv())
print(csv_parser.good_rows)
print(csv_parser.bad_rows)
print(csv_parser.duplicate_rows)
print(csv_parser.log)