#!/usr/bin/python3
# ====================================================================
# demonstrate tabulate module
#
# Note: It only work with a small number of columns and rows
# ====================================================================
import csv
from tabulate import tabulate
# --------------------------------------------------------------------
# ---- use string split
# ----
# ---- Note:
# ---- a. the use of string.split() does not recognize commas
# ---- that are in row columns. the csv module will parse
# ---- a row correctly.
# ---- b. If the return_count is None, all of the CVS
# ---- rows are returned.
# --------------------------------------------------------------------
def collect_raw_csv_data_string_split(filename:str,
return_count:int=None) -> list:
column_count = 0
line_count = 0
header_line = True
with open(filename,'r') as f:
for line in f:
line = line.strip()
line_count += 1
lst = line.split(',')
if header_line:
header_line = False
column_count = len(lst)
print()
print(f'column count = {column_count}')
continue
if len(lst) != column_count:
print('bad column count: ' +\
f'line={line_count:<3} ' +\
f'count={len(lst)}')
# ---- return return_count rows
if return_count is not None:
if row_count > return_count-1: break
print()
print(f'line count = {line_count}')
# --------------------------------------------------------------------
# ---- use CSV module
# ----
# ---- Note: If return_count is None, all of the CVS
# ---- are returned.
# --------------------------------------------------------------------
def collect_raw_csv_data(csvfile:str,
colums:list[int]=None,
return_count:int=None) -> list:
column_count = 0
row_count = 0
header_line = True
lists= []
with open(csvfile,'r',newline='') as f:
csvreader = csv.reader(f,delimiter=',',quotechar='"')
for row in csvreader:
row_count += 1
# ---- file header?
if header_line:
# ---- get the column count of the first row.
# ---- this used to verify the number of
# ---- columns in all of the remaining rows.
column_count = len(row)
# ---- display the row's column names
print()
print('Raw CVS Data Header Column Names')
for i,col in enumerate(row):
print(f'[{i:<2}] {col.replace("_"," ")}')
# ---- skip the header
header_line = False
continue
# ---- this is used to verify the number of
# ---- elements in all rows is the same
if len(row) != column_count:
print('bad column count: ' +\
f'row={row_count:<3} ' +\
f'count={len(row)}')
continue
# ---- return all columns?
if columns is None:
lists.append(row) # save all of the columns
# ---- return selected columns
else:
new_row = []
for col in columns:
new_row.append(row[col])
lists.append(new_row)
# ---- return return_count rows?
if return_count is not None:
if row_count > return_count-1: break
return lists
# --------------------------------------------------------------------
# ---- main
# --------------------------------------------------------------------
if __name__ == '__main__':
filename = 'tabulate_data.csv' # CSV file name
columns = [0,1,8] # selected columns
headers = ['First Name', # header column names
'Last Name',
'Phone Number']
# ---- get raw CSV data (list of lists)
data_rows = collect_raw_csv_data(filename,columns,10)
print()
print(f'{len(data_rows)} rows returned')
print()
# ---- sort by last name
sorted_rows = sorted(data_rows,key=lambda lst:lst[1])
print()
print('---- Unsorted Rows -----------------------------')
print()
for row in data_rows:
print(row)
print()
print('---- Sorted Rows -------------------------------')
print()
for row in sorted_rows:
print(row)
print()
print('---- Simple Table ------------------------------')
print()
print(tabulate(sorted_rows,headers))
print()
print('---- Grid Table --------------------------------')
print()
print(tabulate(sorted_rows,headers,tablefmt="grid"))